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 Test1908 { run()20 public static void run() throws Exception { 21 final Thread spinner = new Thread(() -> { 22 int ret = nativeSpinAndResume(Thread.currentThread()); 23 if (ret != 13) { 24 System.out.println("Got " + ret + " instead of JVMTI_ERROR_THREAD_NOT_SUSPENDED"); 25 } 26 }, "Spinner"); 27 28 final Thread resumer = new Thread(() -> { 29 String me = Thread.currentThread().getName(); 30 31 // wait for the other thread to start spinning. 32 while (!isNativeThreadSpinning()) { } 33 34 System.out.println(me + ": isNativeThreadSpinning() = " + isNativeThreadSpinning()); 35 System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner)); 36 37 // Suspend it from java. 38 Suspension.suspend(spinner); 39 40 System.out.println(me + ": Suspended spinner while native spinning"); 41 System.out.println(me + ": isNativeThreadSpinning() = " + isNativeThreadSpinning()); 42 System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner)); 43 44 System.out.println("Resuming other thread"); 45 nativeResume(); 46 waitForNativeResumeStarted(); 47 // Wait for the other thread to try to resume itself 48 try { Thread.currentThread().sleep(1000); } catch (Exception e) {} 49 50 System.out.println("other thread attempting self resume"); 51 System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner)); 52 53 System.out.println("real resume"); 54 Suspension.resume(spinner); 55 waitForNativeResumeFinished(); 56 System.out.println("other thread resumed."); 57 }, "Resumer"); 58 59 spinner.start(); 60 resumer.start(); 61 62 spinner.join(); 63 resumer.join(); 64 } 65 nativeSpinAndResume(Thread cur)66 public static native int nativeSpinAndResume(Thread cur); nativeResume()67 public static native void nativeResume(); isNativeThreadSpinning()68 public static native boolean isNativeThreadSpinning(); waitForNativeResumeFinished()69 public static native void waitForNativeResumeFinished(); waitForNativeResumeStarted()70 public static native void waitForNativeResumeStarted(); 71 } 72