• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- main.cpp ------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // This test verifies the correct handling of child thread exits.
11 
12 #include <pthread.h>
13 #include <atomic>
14 
15 // Note that although hogging the CPU while waiting for a variable to change
16 // would be terrible in production code, it's great for testing since it
17 // avoids a lot of messy context switching to get multiple threads synchronized.
18 #define do_nothing()
19 
20 #define pseudo_barrier_wait(bar) \
21     --bar;                       \
22     while (bar > 0)              \
23         do_nothing();
24 
25 #define pseudo_barrier_init(bar, count) (bar = count)
26 
27 std::atomic_int g_barrier1;
28 std::atomic_int g_barrier2;
29 std::atomic_int g_barrier3;
30 
31 void *
thread1(void * input)32 thread1 (void *input)
33 {
34     // Synchronize with the main thread.
35     pseudo_barrier_wait(g_barrier1);
36 
37     // Synchronize with the main thread and thread2.
38     pseudo_barrier_wait(g_barrier2);
39 
40     // Return
41     return NULL;                                      // Set second breakpoint here
42 }
43 
44 void *
thread2(void * input)45 thread2 (void *input)
46 {
47     // Synchronize with thread1 and the main thread.
48     pseudo_barrier_wait(g_barrier2);
49 
50     // Synchronize with the main thread.
51     pseudo_barrier_wait(g_barrier3);
52 
53     // Return
54     return NULL;
55 }
56 
main()57 int main ()
58 {
59     pthread_t thread_1;
60     pthread_t thread_2;
61     pthread_t thread_3;
62 
63     pseudo_barrier_init(g_barrier1, 2);
64     pseudo_barrier_init(g_barrier2, 3);
65     pseudo_barrier_init(g_barrier3, 2);
66 
67     // Create a thread.
68     pthread_create (&thread_1, NULL, thread1, NULL);
69 
70     // Wait for thread1 to start.
71     pseudo_barrier_wait(g_barrier1);
72 
73     // Create another thread.
74     pthread_create (&thread_2, NULL, thread2, NULL);  // Set first breakpoint here
75 
76     // Wait for thread2 to start.
77     pseudo_barrier_wait(g_barrier2);
78 
79     // Wait for the first thread to finish
80     pthread_join(thread_1, NULL);
81 
82     // Synchronize with the remaining thread
83     pseudo_barrier_wait(g_barrier3);                  // Set third breakpoint here
84 
85     // Wait for the second thread to finish
86     pthread_join(thread_2, NULL);
87 
88     return 0;                                         // Set fourth breakpoint here
89 }
90