56
57 /* ============================================================================= */
58
59 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
60 const char name[], int foundCount, jthread foundThreads[]);
61
62 /** Agent algorithm. */
63 static void JNICALL
64 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
65
66 NSK_DISPLAY0("Wait for threads to start\n");
67 if (!nsk_jvmti_waitForSync(timeout))
68 return;
69
70 /* perform testing */
71 {
72 jvmtiError* results = NULL;
73 int i;
74
75 NSK_DISPLAY1("Allocate threads array: %d threads\n", threadsCount);
76 if (!NSK_JVMTI_VERIFY(
77 NSK_CPP_STUB3(Allocate, jvmti, (threadsCount * sizeof(jthread)),
78 (unsigned char**)&threads))) {
79 nsk_jvmti_setFailStatus();
80 return;
81 }
82 NSK_DISPLAY1(" ... allocated array: %p\n", (void*)threads);
83
84 NSK_DISPLAY1("Allocate results array: %d threads\n", threadsCount);
85 if (!NSK_JVMTI_VERIFY(
86 NSK_CPP_STUB3(Allocate, jvmti, (threadsCount * sizeof(jvmtiError)),
87 (unsigned char**)&results))) {
88 nsk_jvmti_setFailStatus();
89 return;
90 }
91 NSK_DISPLAY1(" ... allocated array: %p\n", (void*)threads);
92
93 NSK_DISPLAY1("Find threads: %d threads\n", threadsCount);
94 if (!NSK_VERIFY(fillThreadsByName(jvmti, jni, THREAD_NAME, threadsCount, threads)))
95 return;
96
97 NSK_DISPLAY0("Suspend threads list\n");
98 if (!NSK_JVMTI_VERIFY(
99 NSK_CPP_STUB4(SuspendThreadList, jvmti, threadsCount, threads, results))) {
100 nsk_jvmti_setFailStatus();
101 return;
102 }
103
104 NSK_DISPLAY0("Check threads results:\n");
105 for (i = 0; i < threadsCount; i++) {
106 NSK_DISPLAY3(" ... thread #%d: %s (%d)\n",
107 i, TranslateError(results[i]), (int)results[i]);
108 if (!NSK_JVMTI_VERIFY(results[i]))
109 nsk_jvmti_setFailStatus();
110 }
111
112 eventsReceived = 0;
113 NSK_DISPLAY1("Enable event: %s\n", "THREAD_END");
114 if (!nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT, eventsList, NULL))
115 return;
116
117 NSK_DISPLAY0("Let threads to run and finish\n");
118 if (!nsk_jvmti_resumeSync())
119 return;
121 NSK_DISPLAY1("Check that THREAD_END event NOT received for timeout: %ld ms\n", (long)verificationTime);
122 {
123 jlong delta = 1000;
124 jlong time;
125 for (time = 0; time < verificationTime; time += delta) {
126 if (eventsReceived > 0) {
127 NSK_COMPLAIN1("Some threads ran and finished after suspension: %d threads\n",
128 eventsReceived);
129 nsk_jvmti_setFailStatus();
130 break;
131 }
132 nsk_jvmti_sleep(delta);
133 }
134 }
135
136 NSK_DISPLAY1("Disable event: %s\n", "THREAD_END");
137 if (!nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, eventsList, NULL))
138 return;
139
140 NSK_DISPLAY0("Resume threads list\n");
141 if (!NSK_JVMTI_VERIFY(
142 NSK_CPP_STUB4(ResumeThreadList, jvmti, threadsCount, threads, results))) {
143 nsk_jvmti_setFailStatus();
144 return;
145 }
146
147 NSK_DISPLAY0("Wait for thread to finish\n");
148 if (!nsk_jvmti_waitForSync(timeout))
149 return;
150
151 NSK_DISPLAY0("Delete threads references\n");
152 for (i = 0; i < threadsCount; i++) {
153 if (threads[i] != NULL)
154 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threads[i]));
155 }
156
157 NSK_DISPLAY1("Deallocate threads array: %p\n", (void*)threads);
158 if (!NSK_JVMTI_VERIFY(
159 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads))) {
160 nsk_jvmti_setFailStatus();
161 }
162
163 NSK_DISPLAY1("Deallocate results array: %p\n", (void*)results);
164 if (!NSK_JVMTI_VERIFY(
165 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)results))) {
166 nsk_jvmti_setFailStatus();
167 }
168 }
169
170 NSK_DISPLAY0("Let debugee to finish\n");
171 if (!nsk_jvmti_resumeSync())
172 return;
173 }
174
175 /* ============================================================================= */
176
177 /** Find threads whose name starts with specified name prefix. */
178 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
179 const char name[], int foundCount, jthread foundThreads[]) {
180 jint count = 0;
181 jthread* threads = NULL;
182
183 size_t len = strlen(name);
184 int found = 0;
185 int i;
186
187 for (i = 0; i < foundCount; i++) {
188 foundThreads[i] = NULL;
189 }
190
191 if (!NSK_JVMTI_VERIFY(
192 NSK_CPP_STUB3(GetAllThreads, jvmti, &count, &threads))) {
193 nsk_jvmti_setFailStatus();
194 return NSK_FALSE;
195 }
196
197 found = 0;
198 for (i = 0; i < count; i++) {
199 jvmtiThreadInfo info;
200
201 if (!NSK_JVMTI_VERIFY(
202 NSK_CPP_STUB3(GetThreadInfo, jvmti, threads[i], &info))) {
203 nsk_jvmti_setFailStatus();
204 break;
205 }
206
207 if (info.name != NULL && strncmp(name, info.name, len) == 0) {
208 NSK_DISPLAY3(" ... found thread #%d: %p (%s)\n",
209 found, threads[i], info.name);
210 if (found < foundCount)
211 foundThreads[found] = threads[i];
212 found++;
213 }
214
215 }
216
217 if (!NSK_JVMTI_VERIFY(
218 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads))) {
219 nsk_jvmti_setFailStatus();
220 return NSK_FALSE;
221 }
222
223 if (found != foundCount) {
224 NSK_COMPLAIN3("Unexpected number of tested threads found:\n"
225 "# name: %s\n"
226 "# found: %d\n"
227 "# expected: %d\n",
228 name, found, foundCount);
229 nsk_jvmti_setFailStatus();
230 return NSK_FALSE;
231 }
232
233 NSK_DISPLAY1("Make global references for threads: %d threads\n", foundCount);
234 for (i = 0; i < foundCount; i++) {
235 if (!NSK_JNI_VERIFY(jni, (foundThreads[i] = (jthread)
236 NSK_CPP_STUB2(NewGlobalRef, jni, foundThreads[i])) != NULL)) {
237 nsk_jvmti_setFailStatus();
238 return NSK_FALSE;
239 }
240 NSK_DISPLAY2(" ... thread #%d: %p\n", i, foundThreads[i]);
241 }
242
243 return NSK_TRUE;
244 }
245
246 /* ============================================================================= */
247
248 /** THREAD_END callback. */
249 JNIEXPORT void JNICALL
250 callbackThreadEnd(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) {
251 int i;
252
253 /* check if event is for tested thread */
254 for (i = 0; i < threadsCount; i++) {
255 if (thread != NULL &&
256 NSK_CPP_STUB3(IsSameObject, jni, threads[i], thread)) {
257 NSK_DISPLAY2(" ... received THREAD_END event for thread #%d: %p\n",
258 i, (void*)thread);
259 eventsReceived++;
260 return;
261 }
262 }
263 NSK_DISPLAY1(" ... received THREAD_END event for unknown thread: %p\n", (void*)thread);
264 }
265
266 /* ============================================================================= */
267
268 /** Agent library initialization. */
269 #ifdef STATIC_BUILD
270 JNIEXPORT jint JNICALL Agent_OnLoad_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
271 return Agent_Initialize(jvm, options, reserved);
272 }
273 JNIEXPORT jint JNICALL Agent_OnAttach_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
274 return Agent_Initialize(jvm, options, reserved);
275 }
276 JNIEXPORT jint JNI_OnLoad_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
284 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
285 return JNI_ERR;
286
287 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
288
289 /* get options */
290 threadsCount = nsk_jvmti_findOptionIntValue("threads", DEFAULT_THREADS_COUNT);
291 if (!NSK_VERIFY(threadsCount > 0))
292 return JNI_ERR;
293
294 /* create JVMTI environment */
295 if (!NSK_VERIFY((jvmti =
296 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
297 return JNI_ERR;
298
299 /* add specific capabilities for suspending thread */
300 {
301 jvmtiCapabilities suspendCaps;
302 memset(&suspendCaps, 0, sizeof(suspendCaps));
303 suspendCaps.can_suspend = 1;
304 if (!NSK_JVMTI_VERIFY(
305 NSK_CPP_STUB2(AddCapabilities, jvmti, &suspendCaps)))
306 return JNI_ERR;
307 }
308
309 /* set callbacks for THREAD_END event */
310 {
311 jvmtiEventCallbacks callbacks;
312 memset(&callbacks, 0, sizeof(callbacks));
313 callbacks.ThreadEnd = callbackThreadEnd;
314 if (!NSK_JVMTI_VERIFY(
315 NSK_CPP_STUB3(SetEventCallbacks, jvmti, &callbacks, sizeof(callbacks))))
316 return JNI_ERR;
317 }
318
319 /* register agent proc and arg */
320 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
321 return JNI_ERR;
322
323 return JNI_OK;
324 }
325
326 /* ============================================================================= */
327
328 }
|
56
57 /* ============================================================================= */
58
59 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
60 const char name[], int foundCount, jthread foundThreads[]);
61
62 /** Agent algorithm. */
63 static void JNICALL
64 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
65
66 NSK_DISPLAY0("Wait for threads to start\n");
67 if (!nsk_jvmti_waitForSync(timeout))
68 return;
69
70 /* perform testing */
71 {
72 jvmtiError* results = NULL;
73 int i;
74
75 NSK_DISPLAY1("Allocate threads array: %d threads\n", threadsCount);
76 if (!NSK_JVMTI_VERIFY(jvmti->Allocate((threadsCount * sizeof(jthread)),
77 (unsigned char**)&threads))) {
78 nsk_jvmti_setFailStatus();
79 return;
80 }
81 NSK_DISPLAY1(" ... allocated array: %p\n", (void*)threads);
82
83 NSK_DISPLAY1("Allocate results array: %d threads\n", threadsCount);
84 if (!NSK_JVMTI_VERIFY(jvmti->Allocate((threadsCount * sizeof(jvmtiError)),
85 (unsigned char**)&results))) {
86 nsk_jvmti_setFailStatus();
87 return;
88 }
89 NSK_DISPLAY1(" ... allocated array: %p\n", (void*)threads);
90
91 NSK_DISPLAY1("Find threads: %d threads\n", threadsCount);
92 if (!NSK_VERIFY(fillThreadsByName(jvmti, jni, THREAD_NAME, threadsCount, threads)))
93 return;
94
95 NSK_DISPLAY0("Suspend threads list\n");
96 if (!NSK_JVMTI_VERIFY(jvmti->SuspendThreadList(threadsCount, threads, results))) {
97 nsk_jvmti_setFailStatus();
98 return;
99 }
100
101 NSK_DISPLAY0("Check threads results:\n");
102 for (i = 0; i < threadsCount; i++) {
103 NSK_DISPLAY3(" ... thread #%d: %s (%d)\n",
104 i, TranslateError(results[i]), (int)results[i]);
105 if (!NSK_JVMTI_VERIFY(results[i]))
106 nsk_jvmti_setFailStatus();
107 }
108
109 eventsReceived = 0;
110 NSK_DISPLAY1("Enable event: %s\n", "THREAD_END");
111 if (!nsk_jvmti_enableEvents(JVMTI_ENABLE, EVENTS_COUNT, eventsList, NULL))
112 return;
113
114 NSK_DISPLAY0("Let threads to run and finish\n");
115 if (!nsk_jvmti_resumeSync())
116 return;
118 NSK_DISPLAY1("Check that THREAD_END event NOT received for timeout: %ld ms\n", (long)verificationTime);
119 {
120 jlong delta = 1000;
121 jlong time;
122 for (time = 0; time < verificationTime; time += delta) {
123 if (eventsReceived > 0) {
124 NSK_COMPLAIN1("Some threads ran and finished after suspension: %d threads\n",
125 eventsReceived);
126 nsk_jvmti_setFailStatus();
127 break;
128 }
129 nsk_jvmti_sleep(delta);
130 }
131 }
132
133 NSK_DISPLAY1("Disable event: %s\n", "THREAD_END");
134 if (!nsk_jvmti_enableEvents(JVMTI_DISABLE, EVENTS_COUNT, eventsList, NULL))
135 return;
136
137 NSK_DISPLAY0("Resume threads list\n");
138 if (!NSK_JVMTI_VERIFY(jvmti->ResumeThreadList(threadsCount, threads, results))) {
139 nsk_jvmti_setFailStatus();
140 return;
141 }
142
143 NSK_DISPLAY0("Wait for thread to finish\n");
144 if (!nsk_jvmti_waitForSync(timeout))
145 return;
146
147 NSK_DISPLAY0("Delete threads references\n");
148 for (i = 0; i < threadsCount; i++) {
149 if (threads[i] != NULL)
150 NSK_TRACE(jni->DeleteGlobalRef(threads[i]));
151 }
152
153 NSK_DISPLAY1("Deallocate threads array: %p\n", (void*)threads);
154 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)threads))) {
155 nsk_jvmti_setFailStatus();
156 }
157
158 NSK_DISPLAY1("Deallocate results array: %p\n", (void*)results);
159 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)results))) {
160 nsk_jvmti_setFailStatus();
161 }
162 }
163
164 NSK_DISPLAY0("Let debugee to finish\n");
165 if (!nsk_jvmti_resumeSync())
166 return;
167 }
168
169 /* ============================================================================= */
170
171 /** Find threads whose name starts with specified name prefix. */
172 static int fillThreadsByName(jvmtiEnv* jvmti, JNIEnv* jni,
173 const char name[], int foundCount, jthread foundThreads[]) {
174 jint count = 0;
175 jthread* threads = NULL;
176
177 size_t len = strlen(name);
178 int found = 0;
179 int i;
180
181 for (i = 0; i < foundCount; i++) {
182 foundThreads[i] = NULL;
183 }
184
185 if (!NSK_JVMTI_VERIFY(jvmti->GetAllThreads(&count, &threads))) {
186 nsk_jvmti_setFailStatus();
187 return NSK_FALSE;
188 }
189
190 found = 0;
191 for (i = 0; i < count; i++) {
192 jvmtiThreadInfo info;
193
194 if (!NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(threads[i], &info))) {
195 nsk_jvmti_setFailStatus();
196 break;
197 }
198
199 if (info.name != NULL && strncmp(name, info.name, len) == 0) {
200 NSK_DISPLAY3(" ... found thread #%d: %p (%s)\n",
201 found, threads[i], info.name);
202 if (found < foundCount)
203 foundThreads[found] = threads[i];
204 found++;
205 }
206
207 }
208
209 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)threads))) {
210 nsk_jvmti_setFailStatus();
211 return NSK_FALSE;
212 }
213
214 if (found != foundCount) {
215 NSK_COMPLAIN3("Unexpected number of tested threads found:\n"
216 "# name: %s\n"
217 "# found: %d\n"
218 "# expected: %d\n",
219 name, found, foundCount);
220 nsk_jvmti_setFailStatus();
221 return NSK_FALSE;
222 }
223
224 NSK_DISPLAY1("Make global references for threads: %d threads\n", foundCount);
225 for (i = 0; i < foundCount; i++) {
226 if (!NSK_JNI_VERIFY(jni, (foundThreads[i] = (jthread)
227 jni->NewGlobalRef(foundThreads[i])) != NULL)) {
228 nsk_jvmti_setFailStatus();
229 return NSK_FALSE;
230 }
231 NSK_DISPLAY2(" ... thread #%d: %p\n", i, foundThreads[i]);
232 }
233
234 return NSK_TRUE;
235 }
236
237 /* ============================================================================= */
238
239 /** THREAD_END callback. */
240 JNIEXPORT void JNICALL
241 callbackThreadEnd(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread) {
242 int i;
243
244 /* check if event is for tested thread */
245 for (i = 0; i < threadsCount; i++) {
246 if (thread != NULL &&
247 jni->IsSameObject(threads[i], thread)) {
248 NSK_DISPLAY2(" ... received THREAD_END event for thread #%d: %p\n",
249 i, (void*)thread);
250 eventsReceived++;
251 return;
252 }
253 }
254 NSK_DISPLAY1(" ... received THREAD_END event for unknown thread: %p\n", (void*)thread);
255 }
256
257 /* ============================================================================= */
258
259 /** Agent library initialization. */
260 #ifdef STATIC_BUILD
261 JNIEXPORT jint JNICALL Agent_OnLoad_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
262 return Agent_Initialize(jvm, options, reserved);
263 }
264 JNIEXPORT jint JNICALL Agent_OnAttach_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
265 return Agent_Initialize(jvm, options, reserved);
266 }
267 JNIEXPORT jint JNI_OnLoad_suspendthrdlst002(JavaVM *jvm, char *options, void *reserved) {
275 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
276 return JNI_ERR;
277
278 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
279
280 /* get options */
281 threadsCount = nsk_jvmti_findOptionIntValue("threads", DEFAULT_THREADS_COUNT);
282 if (!NSK_VERIFY(threadsCount > 0))
283 return JNI_ERR;
284
285 /* create JVMTI environment */
286 if (!NSK_VERIFY((jvmti =
287 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
288 return JNI_ERR;
289
290 /* add specific capabilities for suspending thread */
291 {
292 jvmtiCapabilities suspendCaps;
293 memset(&suspendCaps, 0, sizeof(suspendCaps));
294 suspendCaps.can_suspend = 1;
295 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&suspendCaps)))
296 return JNI_ERR;
297 }
298
299 /* set callbacks for THREAD_END event */
300 {
301 jvmtiEventCallbacks callbacks;
302 memset(&callbacks, 0, sizeof(callbacks));
303 callbacks.ThreadEnd = callbackThreadEnd;
304 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
305 return JNI_ERR;
306 }
307
308 /* register agent proc and arg */
309 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
310 return JNI_ERR;
311
312 return JNI_OK;
313 }
314
315 /* ============================================================================= */
316
317 }
|