From 2a29ccd3da7c1fd65f36c6cbf9604c71ec61cc7e Mon Sep 17 00:00:00 2001 From: christos Date: Sat, 3 Nov 2012 03:10:50 +0000 Subject: [PATCH] add pthread_condattr_setclock(3) --- lib/libpthread/pthread.h | 5 +++- lib/libpthread/pthread_cond.c | 43 ++++++++++++++++++++++++++----- lib/libpthread/pthread_condattr.3 | 16 ++++++++++-- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lib/libpthread/pthread.h b/lib/libpthread/pthread.h index 166f1ed89f3a..3d3519925bde 100644 --- a/lib/libpthread/pthread.h +++ b/lib/libpthread/pthread.h @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.h,v 1.34 2010/08/06 05:25:02 christos Exp $ */ +/* $NetBSD: pthread.h,v 1.35 2012/11/03 03:10:50 christos Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -112,6 +112,9 @@ int pthread_cond_timedwait(pthread_cond_t * __restrict, int pthread_cond_signal(pthread_cond_t *); int pthread_cond_broadcast(pthread_cond_t *); int pthread_condattr_init(pthread_condattr_t *); +#if defined(_NETBSD_SOURCE) +int pthread_condattr_setclock(pthread_condattr_t *, clockid_t); +#endif int pthread_condattr_destroy(pthread_condattr_t *); int pthread_once(pthread_once_t *, void (*)(void)); diff --git a/lib/libpthread/pthread_cond.c b/lib/libpthread/pthread_cond.c index 896890374f8e..44d8401a20c4 100644 --- a/lib/libpthread/pthread_cond.c +++ b/lib/libpthread/pthread_cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_cond.c,v 1.57 2012/06/15 19:20:44 joerg Exp $ */ +/* $NetBSD: pthread_cond.c,v 1.58 2012/11/03 03:10:50 christos Exp $ */ /*- * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -46,11 +46,12 @@ */ #include -__RCSID("$NetBSD: pthread_cond.c,v 1.57 2012/06/15 19:20:44 joerg Exp $"); +__RCSID("$NetBSD: pthread_cond.c,v 1.58 2012/11/03 03:10:50 christos Exp $"); #include #include #include +#include #include "pthread.h" #include "pthread_int.h" @@ -60,7 +61,7 @@ int _sys___nanosleep50(const struct timespec *, struct timespec *); extern int pthread__started; static int pthread_cond_wait_nothread(pthread_t, pthread_mutex_t *, - const struct timespec *); + pthread_cond_t *, const struct timespec *); int _pthread_cond_has_waiters_np(pthread_cond_t *); @@ -84,6 +85,14 @@ pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) pthread_lockinit(&cond->ptc_lock); PTQ_INIT(&cond->ptc_waiters); cond->ptc_mutex = NULL; + if (attr && attr->ptca_private) { + cond->ptc_private = malloc(sizeof(clockid_t)); + if (cond->ptc_private == NULL) + return errno; + *(clockid_t *)cond->ptc_private = + *(clockid_t *)attr->ptca_private; + } else + cond->ptc_private = NULL; return 0; } @@ -99,6 +108,7 @@ pthread_cond_destroy(pthread_cond_t *cond) cond->ptc_mutex == NULL); cond->ptc_magic = _PT_COND_DEAD; + free(cond->ptc_private); return 0; } @@ -127,7 +137,7 @@ pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, /* Just hang out for a while if threads aren't running yet. */ if (__predict_false(pthread__started == 0)) { - return pthread_cond_wait_nothread(self, mutex, abstime); + return pthread_cond_wait_nothread(self, mutex, cond, abstime); } if (__predict_false(self->pt_cancel)) { pthread__cancelled(); @@ -318,10 +328,28 @@ pthread_condattr_init(pthread_condattr_t *attr) { attr->ptca_magic = _PT_CONDATTR_MAGIC; + attr->ptca_private = NULL; return 0; } +int +pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clck) +{ + switch (clck) { + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + if (attr->ptca_private == NULL) + attr->ptca_private = malloc(sizeof(clockid_t)); + if (attr->ptca_private == NULL) + return errno; + *(clockid_t *)attr->ptca_private = clck; + return 0; + default: + return EINVAL; + } +} + int pthread_condattr_destroy(pthread_condattr_t *attr) { @@ -330,6 +358,7 @@ pthread_condattr_destroy(pthread_condattr_t *attr) attr->ptca_magic == _PT_CONDATTR_MAGIC); attr->ptca_magic = _PT_CONDATTR_DEAD; + free(attr->ptca_private); return 0; } @@ -337,7 +366,7 @@ pthread_condattr_destroy(pthread_condattr_t *attr) /* Utility routine to hang out for a while if threads haven't started yet. */ static int pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex, - const struct timespec *abstime) + pthread_cond_t *cond, const struct timespec *abstime) { struct timespec now, diff; int retval; @@ -346,7 +375,9 @@ pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex, diff.tv_sec = 99999999; diff.tv_nsec = 0; } else { - clock_gettime(CLOCK_REALTIME, &now); + clockid_t clck = cond->ptc_private ? + *(clockid_t *)cond->ptc_private : CLOCK_REALTIME; + clock_gettime(clck, &now); if (timespeccmp(abstime, &now, <)) timespecclear(&diff); else diff --git a/lib/libpthread/pthread_condattr.3 b/lib/libpthread/pthread_condattr.3 index 901b450ebffe..a2b8be86512c 100644 --- a/lib/libpthread/pthread_condattr.3 +++ b/lib/libpthread/pthread_condattr.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: pthread_condattr.3,v 1.7 2010/07/09 17:54:08 jruoho Exp $ +.\" $NetBSD: pthread_condattr.3,v 1.8 2012/11/03 03:10:50 christos Exp $ .\" .\" Copyright (c) 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -50,7 +50,7 @@ .\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $FreeBSD: src/lib/libpthread/man/pthread_condattr.3,v 1.10 2002/09/16 19:29:28 mini Exp $ -.Dd July 9, 2010 +.Dd November 2, 2012 .Dt PTHREAD_CONDATTR 3 .Os .Sh NAME @@ -63,6 +63,8 @@ .Ft int .Fn pthread_condattr_init "pthread_condattr_t *attr" .Ft int +.Fn pthread_condattr_init "pthread_condattr_t *attr" "clockid_t clock" +.Ft int .Fn pthread_condattr_destroy "pthread_condattr_t *attr" .Sh DESCRIPTION Condition attribute objects are used to specify parameters to the @@ -74,6 +76,16 @@ function initializes a condition attribute object with the default attributes and the .Fn pthread_condattr_destroy function destroys a condition attribute object. +The +.Fn pthread_condattr_setclock +function sets the system clock to be used for time comparisons to +the one specified in +.Fa clock . +Valid clock values are +.Dv CLOCK_MONOTONIC +and +.Dv CLOCK_REALTIME +(the default). .Sh RETURN VALUES If successful, these functions return 0. Otherwise, an error number is returned to indicate the error.