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