Threads not waking on pthread_cond_signal()

Ian Wienand <[email protected]>
Newsgroups gmane.comp.lib.phil
Message-ID <[email protected]>
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
[email protected]
http://www.gelato.unsw.edu.au
lowlevellock.h.patch (text/plain, 513 B)
--- 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
wakeup.c (text/plain, 2.2 KB)
#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();
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.