brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · d342939 Raw
110 lines · cpp
1// This test is intended to create a situation in which one thread will exit2// while a breakpoint is being handled in another thread.  This may not always3// happen because it's possible that the exiting thread will exit before the4// breakpoint is hit.  The test case should be flexible enough to treat that5// as success.6 7#include "pseudo_barrier.h"8#include <chrono>9#include <thread>10 11volatile int g_test = 0;12 13// A barrier to synchronize all the threads except the one that will exit.14pseudo_barrier_t g_barrier1;15 16// A barrier to synchronize all the threads including the one that will exit.17pseudo_barrier_t g_barrier2;18 19// A barrier to keep the first group of threads from exiting until after the20// breakpoint has been passed.21pseudo_barrier_t g_barrier3;22 23void *24break_thread_func ()25{26    // Wait until the entire first group of threads is running27    pseudo_barrier_wait(g_barrier1);28 29    // Wait for the exiting thread to start30    pseudo_barrier_wait(g_barrier2);31 32    // Do something33    g_test++;       // Set breakpoint here34 35    // Synchronize after the breakpoint36    pseudo_barrier_wait(g_barrier3);37 38    // Return39    return NULL;40}41 42void *43wait_thread_func ()44{45    // Wait until the entire first group of threads is running46    pseudo_barrier_wait(g_barrier1);47 48    // Wait for the exiting thread to start49    pseudo_barrier_wait(g_barrier2);50 51    // Wait until the breakpoint has been passed52    pseudo_barrier_wait(g_barrier3);53 54    // Return55    return NULL;56}57 58void *59exit_thread_func ()60{61    // Sync up with the rest of the threads.62    pseudo_barrier_wait(g_barrier2);63 64    // Try to make sure this thread doesn't exit until the breakpoint is hit.65    std::this_thread::sleep_for(std::chrono::microseconds(1));66 67    // Return68    return NULL;69}70 71int main ()72{73 74    // The first barrier waits for the non-exiting threads to start.75    // This thread will also participate in that barrier.76    // The idea here is to guarantee that the exiting thread will be77    // last in the internal list maintained by the debugger.78    pseudo_barrier_init(g_barrier1, 5);79 80    // The second break synchronizes thread execution with the breakpoint.81    pseudo_barrier_init(g_barrier2, 5);82 83    // The third barrier keeps the waiting threads around until the breakpoint84    // has been passed.85    pseudo_barrier_init(g_barrier3, 4);86 87    // Create a thread to hit the breakpoint88    std::thread thread_1(break_thread_func);89 90    // Create more threads to slow the debugger down during processing.91    std::thread thread_2(wait_thread_func);92    std::thread thread_3(wait_thread_func);93    std::thread thread_4(wait_thread_func);94 95    // Wait for all these threads to get started.96    pseudo_barrier_wait(g_barrier1);97 98    // Create a thread to exit during the breakpoint99    std::thread thread_5(exit_thread_func);100 101    // Wait for the threads to finish102    thread_5.join();103    thread_4.join();104    thread_3.join();105    thread_2.join();106    thread_1.join();107 108    return 0;109}110