Module Name: src Committed By: bouyer Date: Sat Apr 20 15:14:08 UTC 2013
Modified Files: src/lib/libpthread [netbsd-6]: pthread_cond.c Log Message: Pull up following revision(s) (requested by christos in ticket #862): lib/libpthread/pthread_cond.c: revision 1.60 lib/libpthread/pthread_cond.c: revision 1.61 PR/47703: Yasushi Oshima: pthread_cond_timedwait() does not wait after call pthread_condattr_setclock(CLOCK_MONOTONIC) _lwp_park(2) expects a realtime clock, and it gets passed a monotonic one. Since monotonic < real, it never sleeps. This patch adjusts the monotonic clock to be a real one before it passes is to _lwp_park(2). This is the minimal hacky fix and it will be fixed properly in _lwp_park(2) in the future. XXX: pullup to 6. for safety, declare mono on the outermost block it is used. To generate a diff of this commit: cvs rdiff -u -r1.56.8.1 -r1.56.8.2 src/lib/libpthread/pthread_cond.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libpthread/pthread_cond.c diff -u src/lib/libpthread/pthread_cond.c:1.56.8.1 src/lib/libpthread/pthread_cond.c:1.56.8.2 --- src/lib/libpthread/pthread_cond.c:1.56.8.1 Wed Nov 28 23:47:37 2012 +++ src/lib/libpthread/pthread_cond.c Sat Apr 20 15:14:07 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_cond.c,v 1.56.8.1 2012/11/28 23:47:37 riz Exp $ */ +/* $NetBSD: pthread_cond.c,v 1.56.8.2 2013/04/20 15:14:07 bouyer Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_cond.c,v 1.56.8.1 2012/11/28 23:47:37 riz Exp $"); +__RCSID("$NetBSD: pthread_cond.c,v 1.56.8.2 2013/04/20 15:14:07 bouyer Exp $"); #include <errno.h> #include <sys/time.h> @@ -74,6 +74,13 @@ __strong_alias(__libc_cond_wait,pthread_ __strong_alias(__libc_cond_timedwait,pthread_cond_timedwait) __strong_alias(__libc_cond_destroy,pthread_cond_destroy) +static clockid_t +pthread_cond_getclock(const pthread_cond_t *cond) +{ + return cond->ptc_private ? + *(clockid_t *)cond->ptc_private : CLOCK_REALTIME; +} + int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { @@ -119,6 +126,7 @@ pthread_cond_timedwait(pthread_cond_t *c { pthread_t self; int retval; + struct timespec mono; pthread__error(EINVAL, "Invalid condition variable", cond->ptc_magic == _PT_COND_MAGIC); @@ -127,6 +135,19 @@ pthread_cond_timedwait(pthread_cond_t *c pthread__error(EPERM, "Mutex not locked in condition wait", mutex->ptm_owner != NULL); if (abstime != NULL) { + /* + * XXX: This should be done in the kernel to avoid + * extra system calls! + */ + if (pthread_cond_getclock(cond) == CLOCK_MONOTONIC) { + struct timespec real; + if (clock_gettime(CLOCK_REALTIME, &real) == -1 || + clock_gettime(CLOCK_MONOTONIC, &mono) == -1) + return errno; + timespecsub(abstime, &mono, &mono); + timespecadd(&mono, &real, &mono); + abstime = &mono; + } pthread__error(EINVAL, "Invalid wait time", (abstime->tv_sec >= 0) && (abstime->tv_nsec >= 0) && @@ -375,8 +396,7 @@ pthread_cond_wait_nothread(pthread_t sel diff.tv_sec = 99999999; diff.tv_nsec = 0; } else { - clockid_t clck = cond->ptc_private ? - *(clockid_t *)cond->ptc_private : CLOCK_REALTIME; + clockid_t clck = pthread_cond_getclock(cond); clock_gettime(clck, &now); if (timespeccmp(abstime, &now, <)) timespecclear(&diff);