283 TestClass.m();
284 });
285
286 try {
287 synchronized (LockHolder.lock) {
288 vthread.start();
289 // wait for thread to start and block
290 awaitTrue(started);
291 await(vthread, Thread.State.BLOCKED);
292 }
293 } finally {
294 vthread.join();
295 recording.stop();
296 }
297
298 assertContainsPinnedEvent(recording, vthread);
299 }
300 }
301
302 /**
303 * Test jdk.VirtualThreadPinned event when waiting for a class initializer.
304 */
305 @Test
306 void testWaitingForClassInitializer() throws Exception {
307 class TestClass {
308 static {
309 LockSupport.park();
310 }
311 static void m() {
312 // do nothing
313 }
314 }
315
316 try (Recording recording = new Recording()) {
317 recording.enable("jdk.VirtualThreadPinned");
318 recording.start();
319
320 var started1 = new AtomicBoolean();
321 var started2 = new AtomicBoolean();
322
323 Thread vthread1 = Thread.ofVirtual().unstarted(() -> {
324 started1.set(true);
325 TestClass.m();
326 });
327 Thread vthread2 = Thread.ofVirtual().unstarted(() -> {
328 started2.set(true);
329 TestClass.m();
330 });
331
332 try {
333 // start first virtual thread and wait for it to start + park
334 vthread1.start();
335 awaitTrue(started1);
336 await(vthread1, Thread.State.WAITING);
337
338 // start second virtual thread and wait for it to start
339 vthread2.start();
340 awaitTrue(started2);
341
342 // give time for second virtual thread to wait on the MutexLocker
343 Thread.sleep(3000);
344
345 } finally {
346 LockSupport.unpark(vthread1);
347 vthread1.join();
348 vthread2.join();
349 recording.stop();
350 }
351
352 // the recording should have a pinned event for vthread2
353 assertContainsPinnedEvent(recording, vthread2);
354 }
355 }
356
357 /**
358 * Test jdk.VirtualThreadSubmitFailed event.
359 */
360 @Test
361 void testVirtualThreadSubmitFailed() throws Exception {
362 try (Recording recording = new Recording()) {
|
283 TestClass.m();
284 });
285
286 try {
287 synchronized (LockHolder.lock) {
288 vthread.start();
289 // wait for thread to start and block
290 awaitTrue(started);
291 await(vthread, Thread.State.BLOCKED);
292 }
293 } finally {
294 vthread.join();
295 recording.stop();
296 }
297
298 assertContainsPinnedEvent(recording, vthread);
299 }
300 }
301
302 /**
303 * Test jdk.VirtualThreadPinned event when waiting for a class initializer while pinned.
304 */
305 @Test
306 void testWaitingForClassInitializerWhenPinned() throws Exception {
307 class TestClass {
308 static {
309 LockSupport.park();
310 }
311 static void m() {
312 // do nothing
313 }
314 }
315
316 try (Recording recording = new Recording()) {
317 recording.enable("jdk.VirtualThreadPinned");
318 recording.start();
319
320 var started1 = new AtomicBoolean();
321 var started2 = new AtomicBoolean();
322
323 Thread vthread1 = Thread.ofVirtual().unstarted(() -> {
324 started1.set(true);
325 TestClass.m();
326 });
327 Thread vthread2 = Thread.ofVirtual().unstarted(() -> {
328 started2.set(true);
329 VThreadPinner.runPinned(() -> {
330 TestClass.m();
331 });
332 });
333
334 try {
335 // start first virtual thread and wait for it to start + park
336 vthread1.start();
337 awaitTrue(started1);
338 await(vthread1, Thread.State.WAITING);
339
340 // start second virtual thread and wait for it to start
341 vthread2.start();
342 awaitTrue(started2);
343
344 // give time for second virtual thread to wait in VM
345 Thread.sleep(3000);
346
347 } finally {
348 LockSupport.unpark(vthread1);
349 vthread1.join();
350 vthread2.join();
351 recording.stop();
352 }
353
354 // the recording should have a pinned event for vthread2
355 assertContainsPinnedEvent(recording, vthread2);
356 }
357 }
358
359 /**
360 * Test jdk.VirtualThreadSubmitFailed event.
361 */
362 @Test
363 void testVirtualThreadSubmitFailed() throws Exception {
364 try (Recording recording = new Recording()) {
|