< prev index next >

test/jdk/java/lang/Thread/virtual/JfrEvents.java

Print this page

 45 import java.util.stream.Stream;
 46 
 47 import jdk.jfr.EventType;
 48 import jdk.jfr.Recording;
 49 import jdk.jfr.consumer.RecordedEvent;
 50 import jdk.jfr.consumer.RecordingFile;
 51 
 52 import jdk.test.lib.thread.VThreadPinner;
 53 import jdk.test.lib.thread.VThreadRunner;   // ensureParallelism requires jdk.management
 54 import jdk.test.lib.thread.VThreadScheduler;
 55 import org.junit.jupiter.api.Test;
 56 import org.junit.jupiter.api.BeforeAll;
 57 import org.junit.jupiter.params.ParameterizedTest;
 58 import org.junit.jupiter.params.provider.ValueSource;
 59 import static org.junit.jupiter.api.Assertions.*;
 60 
 61 class JfrEvents {
 62 
 63     @BeforeAll
 64     static void setup() {
 65         int minParallelism = 2;
 66         if (Thread.currentThread().isVirtual()) {
 67             minParallelism++;
 68         }
 69         VThreadRunner.ensureParallelism(minParallelism);
 70     }
 71 
 72     /**
 73      * Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
 74      */
 75     @Test
 76     void testVirtualThreadStartAndEnd() throws Exception {
 77         try (Recording recording = new Recording()) {
 78             recording.enable("jdk.VirtualThreadStart");
 79             recording.enable("jdk.VirtualThreadEnd");
 80 
 81             // execute 100 tasks, each in their own virtual thread
 82             recording.start();
 83             ThreadFactory factory = Thread.ofVirtual().factory();
 84             try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
 85                 for (int i = 0; i < 100; i++) {
 86                     executor.submit(() -> { });
 87                 }
 88                 Thread.sleep(1000); // give time for thread end events to be recorded
 89             } finally {

123                         }
124                     }
125                 });
126             });
127 
128             try {
129                 // wait for thread to start and park
130                 awaitTrue(started);
131                 await(vthread, timed ? Thread.State.TIMED_WAITING : Thread.State.WAITING);
132             } finally {
133                 done.set(true);
134                 LockSupport.unpark(vthread);
135                 vthread.join();
136                 recording.stop();
137             }
138 
139             assertContainsPinnedEvent(recording, vthread);
140         }
141     }
142 

























































































































































































































143     /**
144      * Test jdk.VirtualThreadSubmitFailed event.
145      */
146     @Test
147     void testVirtualThreadSubmitFailed() throws Exception {
148         try (Recording recording = new Recording()) {
149             recording.enable("jdk.VirtualThreadSubmitFailed");
150 
151             recording.start();
152             try (ExecutorService pool = Executors.newCachedThreadPool()) {
153                 Executor scheduler = task -> pool.execute(task);
154 
155                 // create virtual thread that uses custom scheduler
156                 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
157 
158                 // start a thread
159                 Thread thread = factory.newThread(LockSupport::park);
160                 thread.start();
161 
162                 // wait for thread to park

 45 import java.util.stream.Stream;
 46 
 47 import jdk.jfr.EventType;
 48 import jdk.jfr.Recording;
 49 import jdk.jfr.consumer.RecordedEvent;
 50 import jdk.jfr.consumer.RecordingFile;
 51 
 52 import jdk.test.lib.thread.VThreadPinner;
 53 import jdk.test.lib.thread.VThreadRunner;   // ensureParallelism requires jdk.management
 54 import jdk.test.lib.thread.VThreadScheduler;
 55 import org.junit.jupiter.api.Test;
 56 import org.junit.jupiter.api.BeforeAll;
 57 import org.junit.jupiter.params.ParameterizedTest;
 58 import org.junit.jupiter.params.provider.ValueSource;
 59 import static org.junit.jupiter.api.Assertions.*;
 60 
 61 class JfrEvents {
 62 
 63     @BeforeAll
 64     static void setup() {
 65         // need at least two carriers to test pinning
 66         VThreadRunner.ensureParallelism(2);



 67     }
 68 
 69     /**
 70      * Test jdk.VirtualThreadStart and jdk.VirtualThreadEnd events.
 71      */
 72     @Test
 73     void testVirtualThreadStartAndEnd() throws Exception {
 74         try (Recording recording = new Recording()) {
 75             recording.enable("jdk.VirtualThreadStart");
 76             recording.enable("jdk.VirtualThreadEnd");
 77 
 78             // execute 100 tasks, each in their own virtual thread
 79             recording.start();
 80             ThreadFactory factory = Thread.ofVirtual().factory();
 81             try (var executor = Executors.newThreadPerTaskExecutor(factory)) {
 82                 for (int i = 0; i < 100; i++) {
 83                     executor.submit(() -> { });
 84                 }
 85                 Thread.sleep(1000); // give time for thread end events to be recorded
 86             } finally {

120                         }
121                     }
122                 });
123             });
124 
125             try {
126                 // wait for thread to start and park
127                 awaitTrue(started);
128                 await(vthread, timed ? Thread.State.TIMED_WAITING : Thread.State.WAITING);
129             } finally {
130                 done.set(true);
131                 LockSupport.unpark(vthread);
132                 vthread.join();
133                 recording.stop();
134             }
135 
136             assertContainsPinnedEvent(recording, vthread);
137         }
138     }
139 
140     /**
141      * Test jdk.VirtualThreadPinned event when blocking on monitor while pinned.
142      */
143     @Test
144     void testBlockWhenPinned() throws Exception {
145         try (Recording recording = new Recording()) {
146             recording.enable("jdk.VirtualThreadPinned");
147             recording.start();
148 
149             Object lock = new Object();
150 
151             var started = new AtomicBoolean();
152             var vthread = Thread.ofVirtual().unstarted(() -> {
153                 VThreadPinner.runPinned(() -> {
154                     started.set(true);
155                     synchronized (lock) { }
156                 });
157             });
158 
159             try {
160                 synchronized (lock) {
161                     vthread.start();
162                     // wait for thread to start and block
163                     awaitTrue(started);
164                     await(vthread, Thread.State.BLOCKED);
165                 }
166             } finally {
167                 vthread.join();
168                 recording.stop();
169             }
170 
171             assertContainsPinnedEvent(recording, vthread);
172         }
173     }
174 
175     /**
176      * Test jdk.VirtualThreadPinned event when waiting with Object.wait while pinned.
177      */
178     @ParameterizedTest
179     @ValueSource(booleans = { true, false })
180     void testObjectWaitWhenPinned(boolean timed) throws Exception {
181         try (Recording recording = new Recording()) {
182             recording.enable("jdk.VirtualThreadPinned");
183             recording.start();
184 
185             Object lock = new Object();
186 
187             var started = new AtomicBoolean();
188             var vthread = Thread.startVirtualThread(() -> {
189                 VThreadPinner.runPinned(() -> {
190                     started.set(true);
191                     synchronized (lock) {
192                         try {
193                             if (timed) {
194                                 lock.wait(Long.MAX_VALUE);
195                             } else {
196                                 lock.wait();
197                             }
198                         } catch (InterruptedException e) {
199                             fail();
200                         }
201                     }
202                 });
203             });
204 
205             try {
206                 // wait for thread to start and wait
207                 awaitTrue(started);
208                 await(vthread, timed ? Thread.State.TIMED_WAITING : Thread.State.WAITING);
209             } finally {
210                 synchronized (lock) {
211                     lock.notifyAll();
212                 }
213                 vthread.join();
214                 recording.stop();
215             }
216 
217             assertContainsPinnedEvent(recording, vthread);
218         }
219     }
220 
221     /**
222      * Test jdk.VirtualThreadPinned event when parking in a class initializer.
223      */
224     @Test
225     void testParkInClassInitializer() throws Exception {
226         class TestClass {
227             static {
228                 LockSupport.park();
229             }
230             static void m() {
231                 // do nothing
232             }
233         }
234 
235         try (Recording recording = new Recording()) {
236             recording.enable("jdk.VirtualThreadPinned");
237             recording.start();
238 
239             var started = new AtomicBoolean();
240             Thread vthread = Thread.startVirtualThread(() -> {
241                 started.set(true);
242                 TestClass.m();
243             });
244 
245             try {
246                 // wait for it to start and park
247                 awaitTrue(started);
248                 await(vthread, Thread.State.WAITING);
249             } finally {
250                 LockSupport.unpark(vthread);
251                 vthread.join();
252                 recording.stop();
253             }
254 
255             assertContainsPinnedEvent(recording, vthread);
256         }
257     }
258 
259     /**
260      * Test jdk.VirtualThreadPinned event when blocking on monitor in a class initializer.
261      */
262     @Test
263     void testBlockInClassInitializer() throws Exception {
264         class LockHolder {
265             static final Object lock = new Object();
266         }
267         class TestClass {
268             static {
269                 synchronized (LockHolder.lock) { }
270             }
271             static void m() {
272                 // no nothing
273             }
274         }
275 
276         try (Recording recording = new Recording()) {
277             recording.enable("jdk.VirtualThreadPinned");
278             recording.start();
279 
280             var started = new AtomicBoolean();
281             Thread vthread = Thread.ofVirtual().unstarted(() -> {
282                 started.set(true);
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()) {
363             recording.enable("jdk.VirtualThreadSubmitFailed");
364 
365             recording.start();
366             try (ExecutorService pool = Executors.newCachedThreadPool()) {
367                 Executor scheduler = task -> pool.execute(task);
368 
369                 // create virtual thread that uses custom scheduler
370                 ThreadFactory factory = VThreadScheduler.virtualThreadFactory(scheduler);
371 
372                 // start a thread
373                 Thread thread = factory.newThread(LockSupport::park);
374                 thread.start();
375 
376                 // wait for thread to park
< prev index next >