Skip to content

Commit 8329823

Browse files
Serguei Spitsynpull[bot]
authored andcommitted
8328741: serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java failed with unexpected owner
Reviewed-by: lmesnik, cjplummer
1 parent f807f7e commit 8329823

File tree

4 files changed

+34
-94
lines changed

4 files changed

+34
-94
lines changed

test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/ObjectMonitorUsage.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public class ObjectMonitorUsage {
5353
static Object lockCheck = new Object();
5454

5555
native static int getRes();
56-
native static int waitsToEnter();
57-
native static int waitsToBeNotified();
5856
native static int setTestedMonitor(Object monitor);
57+
native static void ensureBlockedOnEnter(Thread thread);
58+
native static void ensureWaitingToBeNotified(Thread thread);
5959
native static void check(Object obj, Thread owner,
6060
int entryCount, int waiterCount, int notifyWaiterCount);
6161

@@ -87,10 +87,9 @@ static Thread[] startWaitingThreads(boolean isVirtual) {
8787
Thread[] threads = new Thread[NUMBER_OF_WAITING_THREADS];
8888
for (int i = 0; i < NUMBER_OF_WAITING_THREADS; i++) {
8989
// the WaitingTask has to wait to be notified in lockCheck.wait()
90-
threads[i] = startTask(i, new WaitingTask(), isVirtual, "Waiting");
91-
}
92-
while (waitsToBeNotified() < NUMBER_OF_WAITING_THREADS) {
93-
sleep(1);
90+
Thread thread = startTask(i, new WaitingTask(), isVirtual, "Waiting");
91+
ensureWaitingToBeNotified(thread);
92+
threads[i] = thread;
9493
}
9594
return threads;
9695
}
@@ -99,10 +98,9 @@ static Thread[] startEnteringThreads(boolean isVirtual) {
9998
Thread[] threads = new Thread[NUMBER_OF_ENTERING_THREADS];
10099
for (int i = 0; i < NUMBER_OF_ENTERING_THREADS; i++) {
101100
// the EnteringTask has to be blocked at the lockCheck enter
102-
threads[i] = startTask(i, new EnteringTask(), isVirtual, "Entering");
103-
}
104-
while (waitsToEnter() < NUMBER_OF_ENTERING_THREADS) {
105-
sleep(1);
101+
Thread thread = startTask(i, new EnteringTask(), isVirtual, "Entering");
102+
ensureBlockedOnEnter(thread);
103+
threads[i] = thread;
106104
}
107105
return threads;
108106
}

test/hotspot/jtreg/serviceability/jvmti/ObjectMonitorUsage/libObjectMonitorUsage.cpp

Lines changed: 6 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@ extern "C" {
3232
#define STATUS_FAILED 2
3333

3434
static jvmtiEnv *jvmti = nullptr;
35-
static jrawMonitorID event_lock = nullptr;
3635
static jint result = PASSED;
3736
static int check_idx = 0;
38-
static int waits_to_enter = 0;
39-
static int waits_to_be_notified = 0;
4037
static jobject tested_monitor = nullptr;
4138

4239
static bool is_tested_monitor(JNIEnv *jni, jobject monitor) {
@@ -53,47 +50,10 @@ static void log_event(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread,
5350
deallocate(jvmti, jni, (void*)tname);
5451
}
5552

56-
JNIEXPORT void JNICALL
57-
MonitorContendedEnter(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jobject monitor) {
58-
RawMonitorLocker rml(jvmti, jni, event_lock);
59-
if (is_tested_monitor(jni, monitor)) {
60-
waits_to_enter++;
61-
log_event(jvmti, jni, thread, "MonitorContendedEnter", waits_to_enter);
62-
}
63-
}
64-
65-
JNIEXPORT void JNICALL
66-
MonitorContendedEntered(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jobject monitor) {
67-
RawMonitorLocker rml(jvmti, jni, event_lock);
68-
if (is_tested_monitor(jni, monitor)) {
69-
waits_to_enter--;
70-
log_event(jvmti, jni, thread, "MonitorContendedEntered", waits_to_enter);
71-
}
72-
}
73-
74-
JNIEXPORT void JNICALL
75-
MonitorWait(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jobject monitor, jlong timeout) {
76-
RawMonitorLocker rml(jvmti, jni, event_lock);
77-
if (is_tested_monitor(jni, monitor)) {
78-
waits_to_be_notified++;
79-
log_event(jvmti, jni, thread, "MonitorWait", waits_to_be_notified);
80-
}
81-
}
82-
83-
JNIEXPORT void JNICALL
84-
MonitorWaited(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jobject monitor, jboolean timed_out) {
85-
RawMonitorLocker rml(jvmti, jni, event_lock);
86-
if (is_tested_monitor(jni, monitor)) {
87-
waits_to_be_notified--;
88-
log_event(jvmti, jni, thread, "MonitorWaited", waits_to_be_notified);
89-
}
90-
}
91-
9253
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
9354
jint res;
9455
jvmtiError err;
9556
jvmtiCapabilities caps;
96-
jvmtiEventCallbacks callbacks;
9757

9858
res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
9959
if (res != JNI_OK || jvmti == nullptr) {
@@ -116,17 +76,6 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
11676
LOG("Warning: Monitor events are not implemented\n");
11777
return JNI_ERR;
11878
}
119-
memset(&callbacks, 0, sizeof(callbacks));
120-
callbacks.MonitorContendedEnter = &MonitorContendedEnter;
121-
callbacks.MonitorContendedEntered = &MonitorContendedEntered;
122-
callbacks.MonitorWait = &MonitorWait;
123-
callbacks.MonitorWaited = &MonitorWaited;
124-
125-
err = jvmti->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
126-
check_jvmti_error(err, "Agent_Initialize: error in JVMTI SetEventCallbacks");
127-
128-
event_lock = create_raw_monitor(jvmti, "Events Monitor");
129-
13079
return JNI_OK;
13180
}
13281

@@ -216,41 +165,20 @@ Java_ObjectMonitorUsage_check(JNIEnv *jni, jclass cls, jobject obj, jthread owne
216165

217166
JNIEXPORT void JNICALL
218167
Java_ObjectMonitorUsage_setTestedMonitor(JNIEnv *jni, jclass cls, jobject monitor) {
219-
jvmtiError err;
220-
jvmtiEventMode event_mode = (monitor != nullptr) ? JVMTI_ENABLE : JVMTI_DISABLE;
221-
222-
RawMonitorLocker rml(jvmti, jni, event_lock);
223-
224168
if (tested_monitor != nullptr) {
225169
jni->DeleteGlobalRef(tested_monitor);
226170
}
227171
tested_monitor = (monitor != nullptr) ? jni->NewGlobalRef(monitor) : nullptr;
228-
waits_to_enter = 0;
229-
waits_to_be_notified = 0;
230-
231-
err = jvmti->SetEventNotificationMode(event_mode, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, nullptr);
232-
check_jvmti_status(jni, err, "setTestedMonitor: error in JVMTI SetEventNotificationMode #1");
233-
234-
err = jvmti->SetEventNotificationMode(event_mode, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, nullptr);
235-
check_jvmti_status(jni, err, "setTestedMonitor: error in JVMTI SetEventNotificationMode #2");
236-
237-
err = jvmti->SetEventNotificationMode(event_mode, JVMTI_EVENT_MONITOR_WAIT, nullptr);
238-
check_jvmti_status(jni, err, "setTestedMonitor: error in JVMTI SetEventNotificationMode #3");
239-
240-
err = jvmti->SetEventNotificationMode(event_mode, JVMTI_EVENT_MONITOR_WAITED, nullptr);
241-
check_jvmti_status(jni, err, "setTestedMonitor: error in JVMTI SetEventNotificationMode #4");
242172
}
243173

244-
JNIEXPORT jint JNICALL
245-
Java_ObjectMonitorUsage_waitsToEnter(JNIEnv *jni, jclass cls) {
246-
RawMonitorLocker rml(jvmti, jni, event_lock);
247-
return waits_to_enter;
174+
JNIEXPORT void JNICALL
175+
Java_ObjectMonitorUsage_ensureBlockedOnEnter(JNIEnv *jni, jclass cls, jthread thread) {
176+
wait_for_state(jvmti, jni, thread, JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER);
248177
}
249178

250-
JNIEXPORT jint JNICALL
251-
Java_ObjectMonitorUsage_waitsToBeNotified(JNIEnv *jni, jclass cls) {
252-
RawMonitorLocker rml(jvmti, jni, event_lock);
253-
return waits_to_be_notified;
179+
JNIEXPORT void JNICALL
180+
Java_ObjectMonitorUsage_ensureWaitingToBeNotified(JNIEnv *jni, jclass cls, jthread thread) {
181+
wait_for_state(jvmti, jni, thread, JVMTI_THREAD_STATE_WAITING_INDEFINITELY);
254182
}
255183

256184
JNIEXPORT jint JNICALL

test/hotspot/jtreg/serviceability/jvmti/vthread/SuspendResumeAll/libSuspendResumeAll.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,7 @@ test_vthread_resume_all(JNIEnv* jni, const jthread* thread_list, int suspend_mas
216216
check_jvmti_status(jni, err, "test_vthread_resume_all: error in JVMTI ResumeAllVirtualThreads");
217217

218218
// wait a second to give the breakpoints a chance to be hit.
219-
#ifdef WINDOWS
220-
Sleep(1000);
221-
#else
222-
sleep(1);
223-
#endif
219+
sleep_sec(1);
224220

225221
for (int idx = 0; idx < EXCLUDE_CNT; idx++) {
226222
// Disable Breakpoint events on excluded thread

test/lib/jdk/test/lib/jvmti/jvmti_common.hpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
#define COMPLAIN LOG
5858

59-
59+
void sleep_ms(int millis);
6060
const char* TranslateState(jint flags);
6161
const char* TranslateError(jvmtiError err);
6262

@@ -380,6 +380,24 @@ find_method(jvmtiEnv *jvmti, JNIEnv *jni, jclass klass, const char* mname) {
380380
return method;
381381
}
382382

383+
// Wait for target thread to reach the required JVMTI thread state.
384+
// The state jint bitmask is returned by the JVMTI GetThreadState.
385+
// Some examples are:
386+
// - JVMTI_THREAD_STATE_WAITING
387+
// - JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
388+
// - JVMTI_THREAD_STATE_SLEEPING
389+
static void
390+
wait_for_state(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jint exp_state) {
391+
while (true) {
392+
// Allow a bitmask to designate expected thread state. E.g., if two bits are expected
393+
// than check they both are present in the state mask returned by JVMTI GetThreadState.
394+
if ((get_thread_state(jvmti, jni, thread) & exp_state) == exp_state) {
395+
break;
396+
}
397+
sleep_ms(100);
398+
}
399+
}
400+
383401
#define MAX_FRAME_COUNT_PRINT_STACK_TRACE 200
384402

385403
static void

0 commit comments

Comments
 (0)