1 /*
  2  * Copyright (c) 2004, 2018, 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  * @test
 26  *
 27  * @summary converted from VM Testbase nsk/jvmti/GetThreadState/thrstat001.
 28  * VM Testbase keywords: [quick, jpda, jvmti, onload_only_logic, noras]
 29  * VM Testbase readme:
 30  * DESCRIPTION
 31  *     The test exercises JVMTI function GetThreadState.  Java program
 32  *     launchs thread and 3 times calls a native method checkStatus. This
 33  *     method calls GetThreadState and checks if the returned value is
 34  *     correct.
 35  *     The test exercises JVMTI function GetThreadState.  Java program
 36  *     launches a thread and 3 times calls a native method checkStatus.
 37  *     This method calls GetThreadState and checks if the returned value is:
 38  *       - JVMTI_THREAD_STATE_RUNNABLE
 39  *               if thread is runnable
 40  *       - JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
 41  *               if thread is waiting to enter sync. block
 42  *       - JVMTI_THREAD_STATE_IN_OBJECT_WAIT
 43  *               if thread is waiting by object.wait()
 44  *     The test also enables JVMPI_EVENT_METHOD_ENTRY and JVMPI_EVENT_METHOD_EXIT
 45  *     events and checks if GetThreadState returns JVMPI_THREAD_RUNNABLE for
 46  *     their threads.
 47  *     Failing criteria for the test are:
 48  *       - value returned by GetThreadState does not match expected value;
 49  *       - failures of used JVMTI functions.
 50  * COMMENTS
 51  *     Converted the test to use GetThreadState instead of GetThreadStatus.
 52  *     The test was updated to be more precise in its thread state transitions.
 53  *     Fixed according to 4387521 bug.
 54  *     To fix bug 4463667,
 55  *         1) two code fragments with "Thread.sleep(500);" are replaced
 56  *            with following ones:
 57  *                 Object obj = new Object();
 58  *                 *
 59  *                 *
 60  *                 synchronized (obj) {
 61  *                     obj.wait(500);
 62  *                 }
 63  *         2) extra waiting time
 64  *                 synchronized (obj) {
 65  *                     obj.wait(500);
 66  *                 }
 67  *            is added to get waiting time certainly after "contendCount"
 68  *            is set to 1.
 69  *     Fixed according to 4669812 bug.
 70  *     Ported from JVMDI.
 71  *     Fixed according to 4925857 bug:
 72  *       - rearranged synchronization of tested thread
 73  *       - enhanced descripton
 74  *
 75  * @library /test/lib
 76  * @run main/othervm/native -agentlib:thrstat01 thrstat01
 77  */
 78 
 79 public class thrstat01 {
 80 
 81     public static final int STATUS_RUNNING = 0;
 82     public static final int STATUS_MONITOR = 1;
 83     public static final int STATUS_WAIT    = 2;
 84 
 85     native static boolean checkStatus0(int statInd);
 86 
 87     static void checkStatus(int statInd) {
 88         if (!checkStatus0(statInd)) {
 89             throw new RuntimeException("Failed");
 90         }
 91     }
 92 
 93     public static void main(String[] args) {
 94         thrstat01 t = new thrstat01();
 95         t.meth();
 96     }
 97 
 98     // barriers for testing thread status values
 99     public static Lock startingMonitor = new Lock();
100     public static Object blockingMonitor = new Object();
101     public static Lock endingMonitor = new Lock();
102 
103     void meth() {
104         TestedThreadThr1 thr = new TestedThreadThr1("tested_thread_thr1");
105 
106         synchronized (blockingMonitor) {
107             synchronized (startingMonitor) {
108                 startingMonitor.val = 0;
109                 thr.start();
110                 while (startingMonitor.val == 0) {
111                     try {
112                         startingMonitor.wait();
113                     } catch (InterruptedException e) {
114                         throw new Error("Unexpected: " + e);
115                     }
116                 }
117             }
118             Thread.yield();
119             checkStatus(STATUS_MONITOR);
120         }
121 
122         synchronized (endingMonitor) {
123             checkStatus(STATUS_WAIT);
124             endingMonitor.val++;
125             endingMonitor.notify();
126         }
127 
128         try {
129             thr.join();
130         } catch (InterruptedException e) {
131             throw new Error("Unexpected: " + e);
132         }
133    }
134 
135     static class Lock {
136         public int val = 0;
137     }
138 }
139 
140 class TestedThreadThr1 extends Thread {
141 
142     public TestedThreadThr1(String name) {
143         super(name);
144     }
145 
146     public void run() {
147         synchronized (thrstat01.endingMonitor) {
148             thrstat01.checkStatus(thrstat01.STATUS_RUNNING);
149             synchronized (thrstat01.startingMonitor) {
150                 thrstat01.startingMonitor.val++;
151                 thrstat01.startingMonitor.notifyAll();
152             }
153 
154             synchronized (thrstat01.blockingMonitor) {
155             }
156 
157             thrstat01.endingMonitor.val = 0;
158             while (thrstat01.endingMonitor.val == 0) {
159                 try {
160                     thrstat01.endingMonitor.wait();
161                 } catch (InterruptedException e) {
162                     throw new Error("Unexpected: " + e);
163                 }
164             }
165         }
166     }
167 }