1
1
/*
2
- * Copyright (c) 2003, 2022 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2003, 2023 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -34,30 +34,46 @@ typedef struct {
34
34
const char **thr_names;
35
35
} info;
36
36
37
+ typedef struct {
38
+ info expected;
39
+ info unexpected;
40
+ } thread_info;
41
+
37
42
static jvmtiEnv *jvmti_env;
38
43
static jrawMonitorID starting_agent_thread_lock;
39
44
static jrawMonitorID stopping_agent_thread_lock;
40
- static int system_threads_count;
41
- static const char *names0[] = {" main" };
42
- static const char *names1[] = {" main" , " thread1" };
43
- static const char *names2[] = {" main" , " Thread-" };
44
- static const char *names3[] = {" main" , " ForkJoinPool-" };
45
45
46
- /*
47
- * Expected number and names of threads started by test for each test point
48
- */
49
- static info expected_thread_info[] = {
50
- {1 , names0}, {1 , names0}, {2 , names1},
51
- {1 , names0}, {2 , names2}, {2 , names3}
46
+ static const char main_name[] = " main" ;
47
+ static const char thread1_name[] = " thread1" ;
48
+ static const char sys_thread_name[] = " SysThread" ;
49
+ // Tes uses -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
50
+ // to make name of carrier thread deterministic
51
+ static const char fj_thread_name[] = " ForkJoinPool-1-worker-1" ;
52
+
53
+ static const char *main_only[] = { main_name };
54
+ static const char *thr1_only[] = { thread1_name };
55
+ static const char *sys_only[] = { sys_thread_name };
56
+ static const char *main_thr1[] = { main_name, thread1_name };
57
+ static const char *main_sys[] = { main_name, sys_thread_name };
58
+ static const char *thr1_sys[] = { thread1_name, sys_thread_name };
59
+ static const char *main_fj[] = { main_name, fj_thread_name };
60
+
61
+ static thread_info thr_info[] = {
62
+ {{1 , main_only}, {2 , thr1_sys}},
63
+ {{1 , main_only}, {2 , thr1_sys}},
64
+ {{2 , main_thr1}, {1 , sys_only}},
65
+ {{1 , main_only}, {2 , thr1_sys}},
66
+ {{2 , main_sys}, {1 , thr1_only}},
67
+ {{2 , main_fj}, {1 , thr1_sys}}
52
68
};
53
69
54
- const char VTHREAD_PREFIX[] = " ForkJoinPool" ;
55
-
56
-
57
70
jthread create_jthread (JNIEnv *jni) {
58
- jclass thrClass = jni->FindClass (" java/lang/Thread" );
59
- jmethodID cid = jni->GetMethodID (thrClass, " <init>" , " ()V" );
60
- return jni->NewObject (thrClass, cid);
71
+ jclass thr_class = jni->FindClass (" java/lang/Thread" );
72
+ jmethodID cid = jni->GetMethodID (thr_class, " <init>" , " (Ljava/lang/String;)V" );
73
+ jstring thread_name = jni->NewStringUTF (sys_thread_name);
74
+ jthread res = jni->NewObject (thr_class, cid, thread_name);
75
+ jni->DeleteLocalRef (thread_name);
76
+ return res;
61
77
}
62
78
63
79
static void JNICALL
@@ -97,54 +113,53 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
97
113
}
98
114
99
115
JNIEXPORT jboolean check_info (JNIEnv *jni, int idx) {
100
- jboolean result = JNI_TRUE;
101
116
jint threads_count = -1 ;
102
117
jthread *threads;
103
- int num_unexpected = 0 ;
118
+ jvmtiThreadInfo inf ;
104
119
105
120
LOG (" >>> Check point: %d\n " , idx);
106
121
107
122
jvmtiError err = jvmti_env->GetAllThreads (&threads_count, &threads);
108
123
check_jvmti_status (jni, err, " Failed in GetAllThreads" );
109
124
125
+ // check unexpected threads
110
126
for (int i = 0 ; i < threads_count; i++) {
111
- if (!isThreadExpected (jvmti_env, threads[i])) {
112
- num_unexpected++;
113
- LOG (" >>> unexpected: " );
114
- } else {
115
- LOG (" >>> expected: " );
127
+ err = jvmti_env->GetThreadInfo (threads[i], &inf);
128
+ check_jvmti_status (jni, err, " Failed in GetThreadInfo" );
129
+ char *name = get_thread_name (jvmti_env, jni, threads[i]);
130
+ LOG (" >>> %s" , name);
131
+
132
+ bool found = false ;
133
+ for (int j = 0 ; j < thr_info[idx].unexpected .cnt && !found; j++) {
134
+ found = strcmp (name, thr_info[idx].unexpected .thr_names [j]) == 0 ;
135
+ }
136
+ if (found) {
137
+ LOG (" Point %d: detected unexpected thread %s\n " , idx, inf.name );
138
+ return JNI_FALSE;
116
139
}
117
- print_thread_info (jvmti_env, jni, threads[i]);
118
140
}
119
141
120
- if (threads_count - num_unexpected != expected_thread_info[idx].cnt + system_threads_count) {
121
- LOG (" Point %d: number of threads expected: %d, got: %d\n " ,
122
- idx, expected_thread_info[idx].cnt + system_threads_count, threads_count - num_unexpected);
123
- return JNI_FALSE;
124
- }
142
+ LOG (" \n " );
125
143
126
- for (int i = 0 ; i < expected_thread_info[idx].cnt ; i++) {
144
+ // verify all expected threads are present
145
+ for (int i = 0 ; i < thr_info[idx].expected .cnt ; i++) {
127
146
bool found = false ;
128
147
for (int j = 0 ; j < threads_count && !found; j++) {
129
148
char *name = get_thread_name (jvmti_env, jni, threads[j]);
130
- found = strstr (name, expected_thread_info[idx].thr_names [i]);
131
- if (found) {
132
- LOG (" >>> found: %s\n " , name);
133
- }
149
+ found = strcmp (name, thr_info[idx].expected .thr_names [i]) == 0 ;
134
150
}
135
-
136
151
if (!found) {
137
- LOG (" Point %d: thread %s not detected\n " , idx, expected_thread_info [idx].thr_names [i]);
138
- result = JNI_FALSE;
152
+ LOG (" Point %d: thread %s not detected\n " , idx, thr_info [idx]. expected .thr_names [i]);
153
+ return JNI_FALSE;
139
154
}
140
155
}
141
156
142
157
deallocate (jvmti_env, jni, threads);
143
-
144
- return result;
158
+ return JNI_TRUE;
145
159
}
146
160
147
- JNIEXPORT void Java_allthr01_startAgentThread (JNIEnv *jni) {
161
+ JNIEXPORT void
162
+ Java_allthr01_startAgentThread (JNIEnv *jni) {
148
163
RawMonitorLocker rml1 = RawMonitorLocker (jvmti_env, jni, starting_agent_thread_lock);
149
164
jvmtiError err = jvmti_env->RunAgentThread (create_jthread (jni),
150
165
sys_thread, NULL ,JVMTI_THREAD_NORM_PRIORITY);
@@ -160,27 +175,6 @@ Java_allthr01_stopAgentThread(JNIEnv *jni) {
160
175
LOG (" Stopped Agent Thread\n " );
161
176
}
162
177
163
-
164
-
165
- JNIEXPORT void JNICALL
166
- Java_allthr01_setSysCnt (JNIEnv *jni, jclass cls) {
167
- jint threadsCount = -1 ;
168
- jthread *threads;
169
-
170
- jvmtiError err = jvmti_env->GetAllThreads (&threadsCount, &threads);
171
- check_jvmti_status (jni,err, " Failed in GetAllThreads" );
172
-
173
- system_threads_count = threadsCount - 1 ;
174
-
175
- for (int i = 0 ; i < threadsCount; i++) {
176
- if (!isThreadExpected (jvmti_env, threads[i])) {
177
- system_threads_count--;
178
- }
179
- }
180
-
181
- LOG (" >>> number of system threads: %d\n " , system_threads_count);
182
- }
183
-
184
178
JNIEXPORT jboolean JNICALL
185
179
Java_allthr01_checkInfo0 (JNIEnv *env, jclass cls, jint expected_idx) {
186
180
return check_info (env, expected_idx);
0 commit comments