NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/47703: pthread_cond_timedwait() does not wait after call pthread_condattr_setclock(CLOCK_MONOTONIC)
>Number: 47703
>Category: lib
>Synopsis: pthread_cond_timedwait() does not wait after call
>pthread_condattr_setclock(CLOCK_MONOTONIC)
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Mar 28 16:15:00 +0000 2013
>Originator: Yasushi Oshima
>Release: 6.1_RC2
>Organization:
>Environment:
NetBSD hassaku 6.1_RC2 NetBSD 6.1_RC2 (GENERIC) #1: Mon Mar 18 08:10:25 JST
2013 oshima@bergamot:/export/netbsd-6/obj/amd64/sys/arch/amd64/compile/GENERIC
amd64
>Description:
pthread_cond_timedwait() does not wait after call
pthread_condattr_setclock(CLOCK_MONOTONIC).
This is a result of a test code (see How To Repeat) which call
pthread_cond_timedwait() set to 10sec:
**** REALTIME clock wait starting
STARTTIME: 1364483493.092059685 sec
TIMEDOUTED: 1364483503.112246279 sec
ELAPSED : 10.020186594 sec
**** REALTIME clock wait ended
**** MONOTONIC clock wait starting
STARTTIME: 508074.001066903 sec
TIMEDOUTED: 508074.001109810 sec
ELAPSED : 0.000042907 sec
**** MONOTONIC clock wait ended
in MONOTONIC, this returned with TIMEDOUTED after only 0.00004sec even setting
as 10sec.
This occurs on both NetBSD 6.1_RC2 and NetBSD-current.
And,
pkgsrc/lang/ruby193-base uses MONOTONIC clock like this.
Some application program of ruby (for example, pkgsrc/net/mikutter) can't
sleep, CPU load becomes 100%.
>How-To-Repeat:
Execute following test code:
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define WAITTIME 10 /* Timeout wait secound */
void *test_thread(void *param)
{
struct timespec ts, to, te;
clockid_t clck;
pthread_condattr_t attr;
pthread_cond_t cond;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int sec, nsec;
int ret=0;
clck= *(clockid_t *)param;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, clck); /* REALTIME or MONOTONIC */
pthread_cond_init(&cond, &attr);
if ((ret = pthread_mutex_lock(&m))) {
fprintf(stderr, "pthread_mutex_lock: %s\n",strerror(ret));
pthread_exit(&ret);
}
clock_gettime(clck, &ts); /* get now */
to = ts;
printf("STARTTIME: %ld.%09ld sec\n", to.tv_sec, to.tv_nsec);
ts.tv_sec += WAITTIME; /* Timeout wait */
if ((ret = pthread_cond_timedwait(&cond, &m, &ts))) {
if (ret == ETIMEDOUT) {
/* Timeout */
clock_gettime(clck, &te);
sec = te.tv_sec-to.tv_sec;
nsec = te.tv_nsec-to.tv_nsec;
if ( nsec < -1 ) {
nsec+=1000*1000*1000;
sec-=1;
}
fprintf(stderr,"TIMEDOUTED: %ld.%09ld sec\n",
te.tv_sec, te.tv_nsec);
fprintf(stderr,"ELAPSED : %d.%09d sec\n", sec, nsec);
} else {
fprintf(stderr, "pthread_cond_timedout:
%s\n",strerror(ret));
pthread_exit(&ret);
}
}
if ((ret = pthread_mutex_unlock(&m))) {
fprintf(stderr, "pthread_mutex_unlock: %s\n",strerror(ret));
pthread_exit(&ret);
}
pthread_exit(&ret);
}
int main(int argc, char* argv[]){
pthread_t child_thread;
clockid_t clck;
/*
* REALTIME clock thread wait
*/
clck = CLOCK_REALTIME;
printf( "**** REALTIME clock wait starting\n");
if (pthread_create(&child_thread, NULL, test_thread, &clck)!=0)
err(1,"pthread_create");
if( pthread_join(child_thread, NULL)!=0) /* wait for terminate */
err(1,"pthread_join");
printf( "**** REALTIME clock wait ended\n");
printf( "\n");
/*
* MONOTONIC clock thread wait
*/
clck = CLOCK_MONOTONIC;
printf( "**** MONOTONIC clock wait starting\n");
if (pthread_create(&child_thread, NULL, test_thread, &clck)!=0)
err(1,"pthread_create");
if( pthread_join(child_thread, NULL)!=0) /* wait for terminate */
err(1,"pthread_join");
printf( "**** MONOTONIC clock wait ended\n");
return 0;
}
>Fix:
I don't know
Home |
Main Index |
Thread Index |
Old Index