98 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.14pseudo_barrier_t g_barrier1;15 16// A barrier to keep the threads from exiting until after the breakpoint has17// been passed.18pseudo_barrier_t g_barrier2;19 20void *21break_thread_func ()22{23 // Wait until all the threads are running24 pseudo_barrier_wait(g_barrier1);25 26 // Wait for the join thread to join27 std::this_thread::sleep_for(std::chrono::microseconds(50));28 29 // Do something30 g_test++; // Set breakpoint here31 32 // Synchronize after the breakpoint33 pseudo_barrier_wait(g_barrier2);34 35 // Return36 return NULL;37}38 39void *40wait_thread_func ()41{42 // Wait until the entire first group of threads is running43 pseudo_barrier_wait(g_barrier1);44 45 // Wait until the breakpoint has been passed46 pseudo_barrier_wait(g_barrier2);47 48 // Return49 return NULL;50}51 52void *53join_thread_func (void *input)54{55 std::thread *thread_to_join = (std::thread *)input;56 57 // Sync up with the rest of the threads.58 pseudo_barrier_wait(g_barrier1);59 60 // Join the other thread61 thread_to_join->join();62 63 // Return64 return NULL;65}66 67int main ()68{69 // The first barrier waits for the non-joining threads to start.70 // This thread will also participate in that barrier.71 // The idea here is to guarantee that the joining thread will be72 // last in the internal list maintained by the debugger.73 pseudo_barrier_init(g_barrier1, 5);74 75 // The second barrier keeps the waiting threads around until the breakpoint76 // has been passed.77 pseudo_barrier_init(g_barrier2, 4);78 79 // Create a thread to hit the breakpoint80 std::thread thread_1(break_thread_func);81 82 // Create more threads to slow the debugger down during processing.83 std::thread thread_2(wait_thread_func);84 std::thread thread_3(wait_thread_func);85 std::thread thread_4(wait_thread_func);86 87 // Create a thread to join the breakpoint thread88 std::thread thread_5(join_thread_func, &thread_1);89 90 // Wait for the threads to finish91 thread_5.join(); // implies thread_1 is already finished92 thread_4.join();93 thread_3.join();94 thread_2.join();95 96 return 0;97}98