problems with pthread_cond_broadcast
Thorsten Kukuk
kukuk at suse.de
Thu Apr 15 05:50:54 UTC 2004
Hi,
I have a problem with pthread_cond_wait/pthread_cond_broadcast
waiting sometimes forever on a fast SMP machine. Attached is a
simple test case.
If I use the order
pthread_mutex_unlock (&lock);
pthread_cond_broadcast (&pcond);
with NPTL, the program will hang after a short time running with
current glibc + NPTL + kernel 2.6.x on all architectures I tested.
If I revert the order to
pthread_cond_broadcast (&pcond);
pthread_mutex_unlock (&lock);
it works fine.
Is this a problem of the test case (since pthread_cond_broadcast and
pthread_cond_wait will access pcond at the same time in different
threads) or is this a glibc/NPTL/kernel problem?
Thanks for any hint,
Thorsten
--
Thorsten Kukuk http://www.suse.de/~kukuk/ kukuk at suse.de
SuSE Linux AG Maxfeldstr. 5 D-90409 Nuernberg
--------------------------------------------------------------------
Key fingerprint = A368 676B 5E1B 3E46 CFCE 2D97 F8FD 4E23 56C6 FB4B
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#define BROKEN 1
#define DEFAULT_NUM_THREADS 64
/* n_readers >= 0 means 0 or more readers */
/* n_readers < 0 means a writer */
pthread_mutex_t lock;
int n_readers;
pthread_cond_t pcond;
void
init_rwlock (void)
{
n_readers = 0;
pthread_mutex_init (&lock, NULL);
pthread_cond_init (&pcond, NULL);
}
void
rw_lock_write ()
{
pthread_mutex_lock (&lock);
while (n_readers != 0)
pthread_cond_wait (&pcond, &lock);
n_readers = -1;
pthread_mutex_unlock (&lock);
}
void
rw_unlock_write (void)
{
pthread_mutex_lock (&lock);
n_readers = 0;
#if BROKEN
pthread_mutex_unlock (&lock);
pthread_cond_broadcast (&pcond);
#else
pthread_cond_broadcast (&pcond);
pthread_mutex_unlock (&lock);
#endif
}
void *
thread_fn (void *data)
{
for (;;)
{
rw_lock_write ();
fprintf (stderr, ".");
rw_unlock_write ();
}
return NULL;
}
int
main (int argc, char *argv[])
{
pthread_t *threads = NULL;
int num_threads = DEFAULT_NUM_THREADS;
int i;
init_rwlock ();
threads = malloc (num_threads * sizeof (pthread_t));
for (i = 0; i < num_threads; i++)
{
assert (pthread_create (&threads[i], NULL, thread_fn, NULL) == 0);
}
for (i = 0; i < num_threads; i++)
{
pthread_join (threads[i], NULL);
}
return 0;
}
More information about the Phil-list
mailing list