[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Threads not waking on pthread_cond_signal()
- From: Ian Wienand <ianw gelato unsw edu au>
- To: phil-list redhat com
- Subject: Threads not waking on pthread_cond_signal()
- Date: Mon, 23 Jun 2003 10:52:04 +1000
Hello,
I am seeing a problem on PowerPC and i386 with NPTL 0.47 where a
thread waiting in pthread_cond_wait() doesn't get woken up on
pthread_cond_signal().
I believe on PowerPC the first attached patch fixes the problem --
since lll_futex_requeue wasn't returning the number of threads moved
no thread ever got woken up.
On i386, I see correct behaviour for a little while, but eventually
the second attached program (wakeup.c) ends up with both threads
hanging in pthread_cond_wait() after about 20 seconds or so. I was
hoping someone more familar with the i386 implementation could have a
look.
For example :
MASTER LOCK MUTEX
FILLED
MASTER UNLOCK MUTEX
MASTER LOCK MUTEX
MASTER COND SIGNAL <--- master signals
MASTER COND WAIT
THREAD TOUCH <--- thread woken up
EMPTIED! <--- thread empties queue
THREAD COND SIGNAL <--- signals for master to wakeup
<--- master should wake up, but it just hangs!
-i
ianw gelato unsw edu au
http://www.gelato.unsw.edu.au
--- nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h.old 2003-06-23 10:25:38.617454632 +1000
+++ nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h 2003-06-23 10:25:51.141550680 +1000
@@ -72,7 +72,7 @@
__ret = INTERNAL_SYSCALL (futex, __err, 5, \
(futexp), FUTEX_REQUEUE, (nr_wake), (nr_move), \
(mutex)); \
- INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret: 0; \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err)? -__ret: __ret; \
})
#ifdef UP
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
/* how many have we done */
unsigned long things_done=0;
/* threads */
pthread_t thread_id;
void *thread(void*);
/* globals */
unsigned long *data_accessed = &things_done;
typedef struct condition_struct {
pthread_mutex_t mutex;
pthread_cond_t empty;
pthread_cond_t full;
unsigned long value;
} condition_t;
condition_t condition = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
/* clear a 'queue' */
void *thread(void *arg) {
while (1) {
printf("THREAD LOCK MUTEX\n"); fflush(NULL);
pthread_mutex_lock( &condition.mutex );
while ( condition.value == 0 ) {
printf("THREAD COND WAIT\n"); fflush(NULL);
pthread_cond_wait( &condition.full, &condition.mutex );
}
printf("THREAD TOUCH\n"); fflush(NULL);
(*data_accessed)++;
condition.value = 0;
printf("EMPTIED!\n"); fflush(NULL);
printf("THREAD COND SIGNAL\n"); fflush(NULL);
pthread_cond_signal( &condition.empty );
printf("THREAD UNLOCK MUTEX\n"); fflush(NULL);
pthread_mutex_unlock( &condition.mutex );
}
}
void do_test(void) {
pthread_t threads[10];
int i = 0;
for ( ; i < 1 ; i++ )
pthread_create( &threads[i], NULL, thread, (void*)NULL );
/* fill a queue, signal to threads to empty it */
while ( 1 ) {
printf("MASTER LOCK MUTEX\n"); fflush(NULL);
pthread_mutex_lock( &condition.mutex );
/* if the queue is full, signal for worker to clean it */
if ( condition.value ) {
printf("MASTER COND SIGNAL \n"); fflush(NULL);
pthread_cond_signal( &condition.full );
printf("MASTER COND WAIT\n"); fflush(NULL);
pthread_cond_wait( &condition.empty , &condition.mutex);
}
printf("MASTER UNLOCK MUTEX\n"); fflush(NULL);
pthread_mutex_unlock( &condition.mutex );
/* fill it back up */
printf("MASTER LOCK MUTEX\n"); fflush(NULL);
pthread_mutex_lock( &condition.mutex );
printf("FILLED\n"); fflush(NULL);
condition.value = 1;
printf("MASTER UNLOCK MUTEX\n"); fflush(NULL);
pthread_mutex_unlock( &condition.mutex );
}
}
/* main */
int main(int argc, char *argv[])
{
do_test();
}
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]