+2014-09-14 Doug Evans <xdje42@gmail.com>
+
+ * 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 <xdje42@gmail.com>
* gdb.threads/queue-signal.c: New file.
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)
{
static void *
sigusr1_thread_function (void *unused)
{
+ incr_thread_count ();
while (!ready)
usleep (100);
pthread_kill (pthread_self (), SIGUSR1);
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)
{
/* 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);