1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package art; 18 19 public class Test1902 { 20 public static final Object lock = new Object(); 21 22 public static volatile boolean OTHER_THREAD_CONTINUE = true; 23 public static volatile boolean OTHER_THREAD_DID_SOMETHING = true; 24 public static volatile boolean OTHER_THREAD_STARTED = false; 25 26 public static class OtherThread implements Runnable { 27 @Override run()28 public void run() { 29 OTHER_THREAD_STARTED = true; 30 while (OTHER_THREAD_CONTINUE) { 31 OTHER_THREAD_DID_SOMETHING = true; 32 } 33 } 34 } 35 waitFor(long millis)36 public static void waitFor(long millis) { 37 try { 38 lock.wait(millis); 39 } catch (Exception e) { 40 System.out.println("Unexpected error: " + e); 41 e.printStackTrace(); 42 } 43 } 44 waitForSuspension(Thread target)45 public static void waitForSuspension(Thread target) { 46 while (!Suspension.isSuspended(target)) { 47 waitFor(100); 48 } 49 } 50 waitForStart()51 public static void waitForStart() { 52 while (!OTHER_THREAD_STARTED) { 53 waitFor(100); 54 } 55 } 56 57 run()58 public static void run() { 59 synchronized (lock) { 60 Thread other = new Thread(new OtherThread(), "TARGET THREAD"); 61 try { 62 other.start(); 63 64 waitForStart(); 65 66 // Try to resume ourself. 67 try { 68 Suspension.resume(Thread.currentThread()); 69 } catch (Exception e) { 70 if (!e.getMessage().equals("JVMTI_ERROR_THREAD_NOT_SUSPENDED")) { 71 System.out.println("incorrect error for resuming a non-suspended thread"); 72 } 73 } 74 try { 75 Suspension.resume(other); 76 } catch (Exception e) { 77 if (!e.getMessage().equals("JVMTI_ERROR_THREAD_NOT_SUSPENDED")) { 78 System.out.println("incorrect error for resuming a non-suspended thread"); 79 } 80 } 81 82 Suspension.suspend(other); 83 // Wait 1 second for the other thread to suspend. 84 waitForSuspension(other); 85 OTHER_THREAD_DID_SOMETHING = false; 86 // Wait a second to see if anything happens. 87 waitFor(1000); 88 89 if (OTHER_THREAD_DID_SOMETHING) { 90 System.out.println("Looks like other thread did something while suspended!"); 91 } 92 // Resume always. 93 Suspension.resume(other); 94 95 // Wait another second. 96 waitFor(1000); 97 98 if (!OTHER_THREAD_DID_SOMETHING) { 99 System.out.println("Doesn't look like the thread unsuspended!"); 100 } 101 102 // Stop the other thread. 103 OTHER_THREAD_CONTINUE = false; 104 // Wait for 1 second for it to die. 105 other.join(1000); 106 107 if (other.isAlive()) { 108 System.out.println("other thread didn't terminate in a reasonable time!"); 109 Runtime.getRuntime().halt(1); 110 } 111 } catch (Throwable t) { 112 System.out.println("something was thrown. Runtime might be in unrecoverable state: " + t); 113 t.printStackTrace(); 114 Runtime.getRuntime().halt(2); 115 } 116 } 117 } 118 } 119