1 // This test verifies the correct handling of child thread exits.
2 
3 #include "pseudo_barrier.h"
4 #include <thread>
5 
6 pseudo_barrier_t g_barrier1;
7 pseudo_barrier_t g_barrier2;
8 pseudo_barrier_t g_barrier3;
9 
10 void *
thread1()11 thread1 ()
12 {
13     // Synchronize with the main thread.
14     pseudo_barrier_wait(g_barrier1);
15 
16     // Synchronize with the main thread and thread2.
17     pseudo_barrier_wait(g_barrier2);
18 
19     // Return
20     return NULL;                                      // Set second breakpoint here
21 }
22 
23 void *
thread2()24 thread2 ()
25 {
26     // Synchronize with thread1 and the main thread.
27     pseudo_barrier_wait(g_barrier2);
28 
29     // Synchronize with the main thread.
30     pseudo_barrier_wait(g_barrier3);
31 
32     // Return
33     return NULL;
34 }
35 
main()36 int main ()
37 {
38     pseudo_barrier_init(g_barrier1, 2);
39     pseudo_barrier_init(g_barrier2, 3);
40     pseudo_barrier_init(g_barrier3, 2);
41 
42     // Create a thread.
43     std::thread thread_1(thread1);
44 
45     // Wait for thread1 to start.
46     pseudo_barrier_wait(g_barrier1);
47 
48     // Create another thread.
49     std::thread thread_2(thread2);  // Set first breakpoint here
50 
51     // Wait for thread2 to start.
52     pseudo_barrier_wait(g_barrier2);
53 
54     // Wait for the first thread to finish
55     thread_1.join();
56 
57     // Synchronize with the remaining thread
58     int dummy = 47;                   // Set third breakpoint here
59     pseudo_barrier_wait(g_barrier3);
60 
61     // Wait for the second thread to finish
62     thread_2.join();
63 
64     return 0;                                         // Set fourth breakpoint here
65 }
66