1*99451b44SJordan Rupprecht // This test is intended to create a situation in which one thread will be 2*99451b44SJordan Rupprecht // created while the debugger is stepping in another thread. 3*99451b44SJordan Rupprecht 4*99451b44SJordan Rupprecht #include "pseudo_barrier.h" 5*99451b44SJordan Rupprecht #include <thread> 6*99451b44SJordan Rupprecht 7*99451b44SJordan Rupprecht #define do_nothing() 8*99451b44SJordan Rupprecht 9*99451b44SJordan Rupprecht pseudo_barrier_t g_barrier; 10*99451b44SJordan Rupprecht 11*99451b44SJordan Rupprecht volatile int g_thread_created = 0; 12*99451b44SJordan Rupprecht volatile int g_test = 0; 13*99451b44SJordan Rupprecht 14*99451b44SJordan Rupprecht void * step_thread_func()15*99451b44SJordan Rupprechtstep_thread_func () 16*99451b44SJordan Rupprecht { 17*99451b44SJordan Rupprecht g_test = 0; // Set breakpoint here 18*99451b44SJordan Rupprecht 19*99451b44SJordan Rupprecht while (!g_thread_created) 20*99451b44SJordan Rupprecht g_test++; 21*99451b44SJordan Rupprecht 22*99451b44SJordan Rupprecht // One more time to provide a continue point 23*99451b44SJordan Rupprecht g_test++; // Continue from here 24*99451b44SJordan Rupprecht 25*99451b44SJordan Rupprecht // Return 26*99451b44SJordan Rupprecht return NULL; 27*99451b44SJordan Rupprecht } 28*99451b44SJordan Rupprecht 29*99451b44SJordan Rupprecht void * create_thread_func(void * input)30*99451b44SJordan Rupprechtcreate_thread_func (void *input) 31*99451b44SJordan Rupprecht { 32*99451b44SJordan Rupprecht std::thread *step_thread = (std::thread*)input; 33*99451b44SJordan Rupprecht 34*99451b44SJordan Rupprecht // Wait until the main thread knows this thread is started. 35*99451b44SJordan Rupprecht pseudo_barrier_wait(g_barrier); 36*99451b44SJordan Rupprecht 37*99451b44SJordan Rupprecht // Wait until the other thread is done. 38*99451b44SJordan Rupprecht step_thread->join(); 39*99451b44SJordan Rupprecht 40*99451b44SJordan Rupprecht // Return 41*99451b44SJordan Rupprecht return NULL; 42*99451b44SJordan Rupprecht } 43*99451b44SJordan Rupprecht main()44*99451b44SJordan Rupprechtint main () 45*99451b44SJordan Rupprecht { 46*99451b44SJordan Rupprecht // Use a simple count to simulate a barrier. 47*99451b44SJordan Rupprecht pseudo_barrier_init(g_barrier, 2); 48*99451b44SJordan Rupprecht 49*99451b44SJordan Rupprecht // Create a thread to hit the breakpoint. 50*99451b44SJordan Rupprecht std::thread thread_1(step_thread_func); 51*99451b44SJordan Rupprecht 52*99451b44SJordan Rupprecht // Wait until the step thread is stepping 53*99451b44SJordan Rupprecht while (g_test < 1) 54*99451b44SJordan Rupprecht do_nothing(); 55*99451b44SJordan Rupprecht 56*99451b44SJordan Rupprecht // Create a thread to exit while we're stepping. 57*99451b44SJordan Rupprecht std::thread thread_2(create_thread_func, &thread_1); 58*99451b44SJordan Rupprecht 59*99451b44SJordan Rupprecht // Wait until that thread is started 60*99451b44SJordan Rupprecht pseudo_barrier_wait(g_barrier); 61*99451b44SJordan Rupprecht 62*99451b44SJordan Rupprecht // Let the stepping thread know the other thread is there 63*99451b44SJordan Rupprecht g_thread_created = 1; 64*99451b44SJordan Rupprecht 65*99451b44SJordan Rupprecht // Wait for the threads to finish. 66*99451b44SJordan Rupprecht thread_2.join(); 67*99451b44SJordan Rupprecht thread_1.join(); 68*99451b44SJordan Rupprecht 69*99451b44SJordan Rupprecht return 0; 70*99451b44SJordan Rupprecht } 71