pthread_cond_broadcast on SMP systems
Bill Spitzak <[email protected]> Fri, 3 Oct 2003 18:11:23 -0700
| Newsgroups | gmane.linux.ngpt.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi! I am developing software at Digital Domain (partially owned by IBM) and
am having some trouble with RedHat 9 on an SMP system and am trying to find
out if there is a bug in pthreads or if I am just using it wrong.
It seems to me that pthread_cond_broadcast does not actually wake up all
threads waiting on the signal, if one of them also did a
pthread_cond_broadcast with the same condition. On older Linux systems and
also on Irix and Windows pthreads emulation I don't seem to have this problem.
The attached program takes one argument, N, which is how many threads to
make. You should also redirect the input from some file. On most systems it
will run until eof, but on RedHat 9 when SMP is enabled (on a 2-processor
machine with Hyperthreading) and threads is set to 3 or more it will hang
rather quickly, with all the threads in wait state.
Recompiling it with -DFIXED will make a working program, where a different
condition is used by the other threads to signal back to the main thread.
This would indicate that setting the same conditions by the receiving thread
is the problem. In my actual code this is quite difficult to work around as
each thread is identical and all are working on parts of the same problem,
though I was able to change all my broadcast/wait calls to new ones that
allocate a temporary condition so only one is used at a time.
Can anybody confirm if this is a bug, or that I am using pthreads wrong?
Please respond directly to spitzak at d2 dot com as I am not subscribed to
the list.
=== cut here ===
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_mutexattr_t attrib = {PTHREAD_MUTEX_RECURSIVE_NP};
pthread_cond_t cond;
#ifdef FIXED
pthread_cond_t cond2;
#define COND2 cond2
#else
#define COND2 cond
#endif
int n = 0;
int m = 0;
void* thread_proc(void* v) {
int i = (int)v;
int pn = 0;
pthread_mutex_lock(&mutex);
for (;;) {
while (n == pn) pthread_cond_wait(&cond, &mutex);
pn = n;
m++;
pthread_cond_broadcast(&COND2);
printf("%*d %d\n", 10*i, i, n);
}
}
pthread_attr_t attr;
pthread_t threads[100];
int main(int argc, char** argv) {
int pm = 0;
int numthreads = atoi(argv[1]);
int i;
pthread_mutex_init(&mutex, &attrib);
pthread_cond_init(&cond, 0);
#ifdef FIXED
pthread_cond_init(&cond2, 0);
#endif
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for (i = 1; i < numthreads; i++)
pthread_create(&threads[i], &attr, thread_proc, (void*)(i));
while (getchar() >= 0) {
pthread_mutex_lock(&mutex);
n = n+1;
printf("%d\n", n);
pthread_cond_broadcast(&cond);
m++;
while (m < pm+numthreads) pthread_cond_wait(&COND2, &mutex);
pm = m;
pthread_mutex_unlock(&mutex);
}
}
=== cut here ===
--
,~,~,~,~ ~ ~ ~ ~
/\_ _|_========___ Bill Spitzak
~~~/\/\\~~~~~~\____________/~~~~~~~~ [email protected]