]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/functionalities/thread/thread_exit/main.cpp
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / functionalities / thread / thread_exit / main.cpp
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 <atomic>
13 #include <thread>
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 *
32 thread1 ()
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 *
45 thread2 ()
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
57 int main ()
58 {
59     pseudo_barrier_init(g_barrier1, 2);
60     pseudo_barrier_init(g_barrier2, 3);
61     pseudo_barrier_init(g_barrier3, 2);
62
63     // Create a thread.
64     std::thread thread_1(thread1);
65
66     // Wait for thread1 to start.
67     pseudo_barrier_wait(g_barrier1);
68
69     // Create another thread.
70     std::thread thread_2(thread2);  // Set first breakpoint here
71
72     // Wait for thread2 to start.
73     pseudo_barrier_wait(g_barrier2);
74
75     // Wait for the first thread to finish
76     thread_1.join();
77
78     // Synchronize with the remaining thread
79     pseudo_barrier_wait(g_barrier3);                  // Set third breakpoint here
80
81     // Wait for the second thread to finish
82     thread_2.join();
83
84     return 0;                                         // Set fourth breakpoint here
85 }