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 Test1920 {
run()20   public static void run() throws Exception {
21     final Thread spinner = new Thread(() -> {
22       nativeSpin();
23     }, "Spinner");
24 
25     final Thread resumer = new Thread(() -> {
26       String me = Thread.currentThread().getName();
27 
28       // wait for the other thread to start spinning.
29       while (!isNativeThreadSpinning()) { }
30 
31       System.out.println(me + ": isNativeThreadSpinning() = " + isNativeThreadSpinning());
32       System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner));
33 
34       // Make the native thread wait before calling monitor-enter.
35       pause();
36       // Reset the marker bit.
37       reset();
38       // Suspend it from java.
39       Suspension.suspend(spinner);
40       // Let the thread try to lock the monitor.
41       resume();
42 
43       // Wait for the other thread to do something.
44       try { Thread.sleep(1000); } catch (Exception e) {}
45 
46       System.out.println(me + ": Suspended spinner while native spinning");
47       System.out.println(me + ": isNativeThreadSpinning() = " + isNativeThreadSpinning());
48       System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner));
49 
50       // Resume it from java. It is still native spinning.
51       Suspension.resume(spinner);
52 
53       System.out.println(me + ": resumed spinner while native spinning");
54 
55       // wait for the other thread to start spinning again.
56       while (!isNativeThreadSpinning()) { }
57 
58       System.out.println(me + ": isNativeThreadSpinning() = " + isNativeThreadSpinning());
59       System.out.println(me + ": isSuspended(spinner) = " + Suspension.isSuspended(spinner));
60       nativeFinish();
61     }, "Resumer");
62 
63     spinner.start();
64     resumer.start();
65 
66     spinner.join();
67     resumer.join();
68   }
69 
nativeSpin()70   public static native void nativeSpin();
nativeFinish()71   public static native void nativeFinish();
reset()72   public static native void reset();
pause()73   public static native void pause();
resume()74   public static native void resume();
isNativeThreadSpinning()75   public static native boolean isNativeThreadSpinning();
76 }
77