1 //===-- main.cpp ------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This test is intended to create a situation in which one thread will exit
11 // while a breakpoint is being handled in another thread. This may not always
12 // happen because it's possible that the exiting thread will exit before the
13 // breakpoint is hit. The test case should be flexible enough to treat that
16 #include "pseudo_barrier.h"
20 volatile int g_test = 0;
22 // A barrier to synchronize all the threads except the one that will exit.
23 pseudo_barrier_t g_barrier1;
25 // A barrier to synchronize all the threads including the one that will exit.
26 pseudo_barrier_t g_barrier2;
28 // A barrier to keep the first group of threads from exiting until after the
29 // breakpoint has been passed.
30 pseudo_barrier_t g_barrier3;
35 // Wait until the entire first group of threads is running
36 pseudo_barrier_wait(g_barrier1);
38 // Wait for the exiting thread to start
39 pseudo_barrier_wait(g_barrier2);
42 g_test++; // Set breakpoint here
44 // Synchronize after the breakpoint
45 pseudo_barrier_wait(g_barrier3);
54 // Wait until the entire first group of threads is running
55 pseudo_barrier_wait(g_barrier1);
57 // Wait for the exiting thread to start
58 pseudo_barrier_wait(g_barrier2);
60 // Wait until the breakpoint has been passed
61 pseudo_barrier_wait(g_barrier3);
70 // Sync up with the rest of the threads.
71 pseudo_barrier_wait(g_barrier2);
73 // Try to make sure this thread doesn't exit until the breakpoint is hit.
74 std::this_thread::sleep_for(std::chrono::microseconds(1));
83 // The first barrier waits for the non-exiting threads to start.
84 // This thread will also participate in that barrier.
85 // The idea here is to guarantee that the exiting thread will be
86 // last in the internal list maintained by the debugger.
87 pseudo_barrier_init(g_barrier1, 5);
89 // The second break synchronizes thread execution with the breakpoint.
90 pseudo_barrier_init(g_barrier2, 5);
92 // The third barrier keeps the waiting threads around until the breakpoint
94 pseudo_barrier_init(g_barrier3, 4);
96 // Create a thread to hit the breakpoint
97 std::thread thread_1(break_thread_func);
99 // Create more threads to slow the debugger down during processing.
100 std::thread thread_2(wait_thread_func);
101 std::thread thread_3(wait_thread_func);
102 std::thread thread_4(wait_thread_func);
104 // Wait for all these threads to get started.
105 pseudo_barrier_wait(g_barrier1);
107 // Create a thread to exit during the breakpoint
108 std::thread thread_5(exit_thread_func);
110 // Wait for the threads to finish