diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c1feb31baa..8a147f676f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-09-14 Doug Evans + + * gdb.threads/queue-signal.c (thread_count): New variable. + (thread_count_mutex, thread_count_condvar): New variables. + (incr_thread_count, wait_all_threads_running): New functions. + (main): Wait for all threads to be in their thread functions. + 2014-09-13 Doug Evans * gdb.threads/queue-signal.c: New file. diff --git a/gdb/testsuite/gdb.threads/queue-signal.c b/gdb/testsuite/gdb.threads/queue-signal.c index 147f2f75b2..5ab0c95bce 100644 --- a/gdb/testsuite/gdb.threads/queue-signal.c +++ b/gdb/testsuite/gdb.threads/queue-signal.c @@ -27,6 +27,20 @@ sig_atomic_t sigusr1_received; sig_atomic_t sigusr2_received; sig_atomic_t sigabrt_received; +/* Number of threads currently running. */ +int thread_count; +pthread_mutex_t thread_count_mutex; +pthread_cond_t thread_count_condvar; + +static void +incr_thread_count (void) +{ + pthread_mutex_lock (&thread_count_mutex); + ++thread_count; + pthread_cond_signal (&thread_count_condvar); + pthread_mutex_unlock (&thread_count_mutex); +} + static void sigusr1_handler (int sig) { @@ -48,6 +62,7 @@ sigabrt_handler (int sig) static void * sigusr1_thread_function (void *unused) { + incr_thread_count (); while (!ready) usleep (100); pthread_kill (pthread_self (), SIGUSR1); @@ -56,11 +71,31 @@ sigusr1_thread_function (void *unused) static void * sigusr2_thread_function (void *unused) { + incr_thread_count (); while (!ready) usleep (100); /* pthread_kill (pthread_self (), SIGUSR2); - manually injected by gdb */ } +/* Wait until all threads are at a point where a backtrace will + show the thread entry point function. */ + +static void +wait_all_threads_running (int nr_threads) +{ + pthread_mutex_lock (&thread_count_mutex); + + while (1) + { + if (thread_count == nr_threads) + { + pthread_mutex_unlock (&thread_count_mutex); + return; + } + pthread_cond_wait (&thread_count_condvar, &thread_count_mutex); + } +} + static void all_threads_running (void) { @@ -88,8 +123,13 @@ main () /* Don't let any thread advance past initialization. */ ready = 0; + pthread_mutex_init (&thread_count_mutex, NULL); + pthread_cond_init (&thread_count_condvar, NULL); + +#define NR_THREADS 2 pthread_create (&sigusr1_thread, NULL, sigusr1_thread_function, NULL); pthread_create (&sigusr2_thread, NULL, sigusr2_thread_function, NULL); + wait_all_threads_running (NR_THREADS); all_threads_running (); pthread_kill (pthread_self (), SIGABRT);