[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Threads not waking on pthread_cond_signal()
- From: Ian Wienand <ianw gelato unsw edu au>
- To: Ulrich Drepper <drepper redhat com>
- Cc: phil-list redhat com
- Subject: Re: Threads not waking on pthread_cond_signal()
- Date: Mon, 23 Jun 2003 13:11:00 +1000
On Sun, Jun 22, 2003 at 06:42:03PM -0700, Ulrich Drepper wrote:
> > 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().
>
> What kernel are you using?
2.5.72 -- but I get correct behaviour with NPTL 0.48 so it was
probably me.
However, i386 does seem to be a lot slower signalling threads than the
NPTL included in RedHat 9.
RUNNING REDHAT 9 WAKEUP TEST
718674 wakes ups in 4.99956 sec = 143748 per second
861807 wakes ups in 5 sec = 172361 per second
841964 wakes ups in 5.00006 sec = 168391 per second
816596 wakes ups in 5.00003 sec = 163318 per second
624066 wakes ups in 5.00004 sec = 124812 per second
RUNNING NPTL 0.48 WAKEUP TEST
114766 wakes ups in 4.99935 sec = 22956 per second
168681 wakes ups in 4.99996 sec = 33736 per second
286987 wakes ups in 4.99985 sec = 57399 per second
286391 wakes ups in 4.99962 sec = 57283 per second
337517 wakes ups in 5.00024 sec = 67500 per second
My iBook running 2.5.72/NPTL0.48 (from
bk://ppc.bkbits.net/linuxppc-2.5) gives me figures comprable to the
Redhat 9 figures.
You should be able to replicate this with the attached two files.
gcc -O2 -lpthread -o wakeup wakeup.c
If you think the test is not measuring what it should I would be
interested in why.
-i
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
/* the time to run each test */
#define TIME_TO_WAIT 5
/* FOR EACH TEST DEFINE : */
/* define a ul in your test that says how many things it did */
extern unsigned long things_done;
/* define a string in your test to say what it wasd doing */
extern char * things;
/* a function (that doesn't return) to run your test */
void do_test(void);
struct timeval start,end;
/* on alarm print out results */
void on_alarm(int signo)
{
struct timeval diff ;
double diff_secs;
/* grab things done before we continue as we do not kill
the potentially running threads until we exit below */
unsigned long stamp = things_done;
gettimeofday(&end, NULL);
timersub( &end, &start , &diff );
diff_secs = diff.tv_sec + diff.tv_usec*1e-6;
printf("%d %s in %.4g sec = ", stamp, things, diff_secs);
printf("%.0f per second\n", stamp / diff_secs );
exit(0);
}
/* main */
int main(int argc, char *argv[])
{
/* setup alarm handler */
static struct sigaction alarm_m;
alarm_m.sa_handler = on_alarm;
sigfillset(&(alarm_m.sa_mask));
sigaction(SIGALRM , &alarm_m, NULL);
alarm( TIME_TO_WAIT );
gettimeofday( &start , NULL );
do_test();
sleep(TIME_TO_WAIT + 10);
}
#include "thread.c"
/* what are we doing */
char *things = "wakes ups";
/* 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) {
pthread_mutex_lock( &condition.mutex );
while ( condition.value == 0 )
pthread_cond_wait( &condition.full, &condition.mutex );
(*data_accessed)++;
condition.value = 0;
#ifdef DEBUG
printf("EMPTIED!");
#endif
pthread_cond_signal( &condition.empty );
pthread_mutex_unlock( &condition.mutex );
}
}
void do_test(void) {
pthread_t threads[10];
int i = 0;
/* have 10 workers */
for ( ; i < 10 ; i++ )
pthread_create( &threads[i], NULL, thread, (void*)NULL );
/* fill a queue, signal to threads to empty it */
while ( 1 ) {
pthread_mutex_lock( &condition.mutex );
/* if the queue is full, signal for worker to clean it */
if ( condition.value ) {
pthread_cond_signal( &condition.full );
pthread_cond_wait( &condition.empty , &condition.mutex);
}
pthread_mutex_unlock( &condition.mutex );
/* fill it back up */
pthread_mutex_lock( &condition.mutex );
#ifdef DEBUG
printf("FILLED\n");
#endif
condition.value = 1;
pthread_mutex_unlock( &condition.mutex );
}
}
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]