1 /*
  2  * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 
 25 /*
 26  * @test
 27  *
 28  * @summary converted from VM Testbase nsk/jvmti/GetCurrentContendedMonitor/contmon01.
 29  * VM Testbase keywords: [quick, jpda, jvmti, noras]
 30  * VM Testbase readme:
 31  * DESCRIPTION
 32  *     The test exercises JVMTI function GetCurrentContendedMonitor.
 33  *     The test cases include:
 34  *       - current contended monitor: present or not;
 35  *       - thread: current, non-current;
 36  *       - thread waiting to enter a monitor or after wait();
 37  *     Failing criteria for the test are:
 38  *       - object returned by GetCurrentContendedMonitor is not the same
 39  *         as expected;
 40  *       - failures of used JVMTI functions.
 41  * COMMENTS
 42  *     By today, the test is referred from two bugs, 4327280 and 4463667
 43  *     To fix bug 4463667, one code fragment with "Thread.sleep(500);"
 44  *     is replaced with following one:
 45  *         Object obj = new Object();
 46  *             *
 47  *             *
 48  *         synchronized (obj) {
 49  *             obj.wait(500);
 50  *         }
 51  *     Note. Until 4327280 gets fixing, the correction cannot be tested.
 52  *     Fixed according to 4509016 bug.
 53  *     Fixed according to 4669812 bug.
 54  *     The test was fixed due to the following bug:
 55  *         4762695 nsk/jvmti/GetCurrentContendedMonitor/contmon01 has an
 56  *                 incorrect test
 57  *     Ported from JVMDI.
 58  *     Fixed according to 4925857 bug:
 59  *       - rearranged synchronization of tested thread
 60  *       - enhanced descripton
 61  *
 62  * @library /test/lib
 63  * @compile --enable-preview -source ${jdk.version} contmon01.java
 64  * @run main/othervm/native --enable-preview -agentlib:contmon01 contmon01
 65  */
 66 
 67 public class contmon01 {
 68 
 69     native static void checkMonitor(int point, Thread thread, Object monitor);
 70 
 71     static {
 72         System.loadLibrary("contmon01");
 73     }
 74 
 75     public static volatile boolean startingBarrier = true;
 76     public static volatile boolean waitingBarrier = true;
 77     static Object lockFld = new Object();
 78     
 79     public static void doSleep() {
 80         try {
 81             Thread.sleep(10);
 82         } catch (Exception e) {
 83             throw new Error("Unexpected " + e);
 84         }
 85     }
 86 
 87     public static void main(String argv[]) {
 88         test(false);
 89         test(true);
 90     }
 91 
 92     public static void test(boolean isVirtual) {
 93         startingBarrier = true;
 94         waitingBarrier = true;
 95         Object lock = new Object();
 96         Thread currThread = Thread.currentThread();
 97 
 98         System.out.println("\nCheck #1: verifying a contended monitor of current thread \""
 99                 + currThread.getName() + "\" ...");
100         synchronized (lock) {
101             checkMonitor(1, currThread, null);
102         }
103         System.out.println("Check #1 done");
104 
105         contmon01Task task = new contmon01Task();
106 
107         Thread thread = isVirtual ? Thread.ofVirtual().start(task) : Thread.ofPlatform().start(task);
108 
109         System.out.println("\nWaiting for auxiliary thread ...");
110         while (startingBarrier) {
111             doSleep();
112         }
113         System.out.println("Auxiliary thread is ready");
114 
115         System.out.println("\nCheck #3: verifying a contended monitor of auxiliary thread ...");
116         checkMonitor(3, thread, null);
117         System.out.println("Check #3 done");
118 
119         task.letItGo();
120 
121         while (waitingBarrier) {
122             doSleep();
123         }
124         synchronized (lockFld) {
125             System.out.println("\nMain thread entered lockFld's monitor"
126                     + "\n\tand calling lockFld.notifyAll() to awake auxiliary thread");
127             lockFld.notifyAll();
128             System.out.println("\nCheck #4: verifying a contended monitor of auxiliary thread ...");
129             checkMonitor(4, thread, lockFld);
130             System.out.println("Check #4 done");
131         }
132 
133         System.out.println("\nMain thread released lockFld's monitor"
134                 + "\n\tand waiting for auxiliary thread death ...");
135 
136         try {
137             thread.join();
138         } catch (InterruptedException e) {
139             throw new Error("Unexpected " + e);
140         }
141         System.out.println("\nCheck #5: verifying a contended monitor of dead auxiliary thread ...");
142         checkMonitor(5, thread, null);
143         System.out.println("Check #5 done");
144     }
145 }
146 
147 
148 class contmon01Task implements Runnable {
149     private volatile boolean flag = true;
150 
151     public void run() {
152         System.out.println("check #2: verifying a contended monitor of current auxiliary thread ...");
153         contmon01.checkMonitor(2, Thread.currentThread(), null);
154         System.out.println("check #2 done");
155 
156         System.out.println("notifying main thread");
157         contmon01.startingBarrier = false;
158 
159         System.out.println("thread is going to loop while <flag> is true ...");
160         int i = 0;
161         int n = 1000;
162         while (flag) {
163             if (n <= 0) {
164                 n = 1000;
165                 // no contmon01.doSleep() is allowed here as it can grab a lock
166             }
167             if (i > n) {
168                 i = 0;
169                 n--;
170             }
171             i++;
172         }
173         System.out.println("looping is done: <flag> is false");
174 
175         synchronized (contmon01.lockFld) {
176             contmon01.waitingBarrier = false;
177             System.out.println("\nthread entered lockFld's monitor"
178                     + "\n\tand releasing it through the lockFld.wait() call");
179             try {
180                 contmon01.lockFld.wait();
181             } catch (InterruptedException e) {
182                 throw new Error("Unexpected " + e);
183             }
184         }
185 
186         System.out.println("thread exiting");
187     }
188 
189     public void letItGo() {
190         flag = false;
191     }
192 }