Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Nov 2010 07:53:09 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r214773 - in user/davidxu/libthr: lib/libthr/thread sys/kern sys/sys
Message-ID:  <201011040753.oA47r9aI048243@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidxu
Date: Thu Nov  4 07:53:09 2010
New Revision: 214773
URL: http://svn.freebsd.org/changeset/base/214773

Log:
  Introduce cv_wait options: CVWAIT_ABSTIME and CVWAIT_CLOCKID.
  CVWAIT_ABSTIME indicates the timeout is absolute time.
  CVWAIT_CLOCKID indicats the clockid should be retrieved from
  condition variable field c_clockid. This is how POSIX condition
  varible works.

Modified:
  user/davidxu/libthr/lib/libthr/thread/thr_cond.c
  user/davidxu/libthr/lib/libthr/thread/thr_private.h
  user/davidxu/libthr/lib/libthr/thread/thr_umtx.c
  user/davidxu/libthr/sys/kern/kern_umtx.c
  user/davidxu/libthr/sys/sys/_umtx.h
  user/davidxu/libthr/sys/sys/umtx.h

Modified: user/davidxu/libthr/lib/libthr/thread/thr_cond.c
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_cond.c	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/lib/libthr/thread/thr_cond.c	Thu Nov  4 07:53:09 2010	(r214773)
@@ -74,11 +74,11 @@ cond_init(pthread_cond_t *cond, const pt
 		 * Initialise the condition variable structure:
 		 */
 		if (cond_attr == NULL || *cond_attr == NULL) {
-			pcond->c_pshared = 0;
-			pcond->c_clockid = CLOCK_REALTIME;
+			pcond->c_kerncv.c_clockid = CLOCK_REALTIME;
 		} else {
-			pcond->c_pshared = (*cond_attr)->c_pshared;
-			pcond->c_clockid = (*cond_attr)->c_clockid;
+			if ((*cond_attr)->c_pshared)
+				pcond->c_kerncv.c_flags |= USYNC_PROCESS_SHARED;
+			pcond->c_kerncv.c_clockid = (*cond_attr)->c_clockid;
 		}
 		pcond->c_kerncv.c_flags |= UCOND_BIND_MUTEX;
 		*cond = pcond;
@@ -162,7 +162,6 @@ cond_wait_common(pthread_cond_t *cond, p
 	const struct timespec *abstime, int cancel)
 {
 	struct pthread	*curthread = _get_curthread();
-	struct timespec ts, ts2, *tsp;
 	pthread_cond_t  cv;
 	struct pthread_mutex *m;
 	int	recurse;
@@ -180,19 +179,14 @@ cond_wait_common(pthread_cond_t *cond, p
 		return (ret);
 	m = *mutex;
 
-	if (abstime != NULL) {
-		clock_gettime(cv->c_clockid, &ts);
-		TIMESPEC_SUB(&ts2, abstime, &ts);
-		tsp = &ts2;
-	} else
-		tsp = NULL;
-
 	if (cancel) {
 		_thr_cancel_enter2(curthread, 0);
-		ret = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, tsp, 0);
+		ret = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, abstime,
+			CVWAIT_ABSTIME|CVWAIT_CLOCKID);
 		_thr_cancel_leave(curthread, 0);
 	} else {
-		ret = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, tsp, 0);
+		ret = _thr_ucond_wait(&cv->c_kerncv, &m->m_lock, abstime,
+			CVWAIT_ABSTIME|CVWAIT_CLOCKID);
 	}
 
 	if (ret == 0) {

Modified: user/davidxu/libthr/lib/libthr/thread/thr_private.h
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_private.h	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/lib/libthr/thread/thr_private.h	Thu Nov  4 07:53:09 2010	(r214773)
@@ -169,8 +169,6 @@ struct pthread_mutex_attr {
 
 struct pthread_cond {
 	struct ucond	c_kerncv;
-	int		c_pshared;
-	int		c_clockid;
 };
 
 struct pthread_cond_attr {

Modified: user/davidxu/libthr/lib/libthr/thread/thr_umtx.c
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_umtx.c	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/lib/libthr/thread/thr_umtx.c	Thu Nov  4 07:53:09 2010	(r214773)
@@ -180,12 +180,6 @@ int
 _thr_ucond_wait(struct ucond *cv, struct umutex *m,
 	const struct timespec *timeout, int flags)
 {
-	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
-	    timeout->tv_nsec <= 0))) {
-		struct pthread *curthread = _get_curthread();
-		_thr_umutex_unlock(m, TID(curthread));
-                return (ETIMEDOUT);
-	}
 	return _umtx_op_err(cv, UMTX_OP_CV_WAIT, flags,
 		     m, __DECONST(void*, timeout));
 }

Modified: user/davidxu/libthr/sys/kern/kern_umtx.c
==============================================================================
--- user/davidxu/libthr/sys/kern/kern_umtx.c	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/sys/kern/kern_umtx.c	Thu Nov  4 07:53:09 2010	(r214773)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysent.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
+#include <sys/syscallsubr.h>
 #include <sys/eventhandler.h>
 #include <sys/umtx.h>
 
@@ -2486,6 +2487,7 @@ do_cv_wait(struct thread *td, struct uco
 	struct timespec cts, ets, tts;
 	struct umtxq_chain *old_chain;
 	uint32_t flags, mflags;
+	uint32_t clockid;
 	int error;
 
 	uq = td->td_umtxq;
@@ -2494,6 +2496,18 @@ do_cv_wait(struct thread *td, struct uco
 	error = umtx_key_get(cv, TYPE_CV, GET_SHARE(flags), &uq->uq_key);
 	if (error != 0)
 		return (error);
+
+	if ((wflags & CVWAIT_CLOCKID) != 0) {
+		clockid = fuword32(&cv->c_clockid);
+		if (clockid < CLOCK_REALTIME ||
+		    clockid >= CLOCK_THREAD_CPUTIME_ID) {
+			/* hmm, only HW clock id will work. */
+			return (EINVAL);
+		}
+	} else {
+		clockid = CLOCK_REALTIME;
+	}
+
 	savekey = uq->uq_key;
 	if ((flags & UCOND_BIND_MUTEX) != 0) {
 		if ((mflags & UMUTEX_PRIO_INHERIT) != 0)
@@ -2549,14 +2563,22 @@ ignore:
 		if (timeout == NULL) {
 			error = umtxq_sleep(uq, "ucond", 0);
 		} else {
-			getnanouptime(&ets);
-			timespecadd(&ets, timeout);
-			TIMESPEC_TO_TIMEVAL(&tv, timeout);
+			if ((wflags & CVWAIT_ABSTIME) == 0) {
+				kern_clock_gettime(td, clockid, &ets);
+				timespecadd(&ets, timeout);
+				tts = *timeout;
+			} else { /* absolute time */
+				ets = *timeout;
+				tts = *timeout;
+				kern_clock_gettime(td, clockid, &cts);
+				timespecsub(&tts, &cts);
+			}
+			TIMESPEC_TO_TIMEVAL(&tv, &tts);
 			for (;;) {
 				error = umtxq_sleep(uq, "ucond", tvtohz(&tv));
 				if (error != ETIMEDOUT)
 					break;
-				getnanouptime(&cts);
+				kern_clock_gettime(td, clockid, &cts);
 				if (timespeccmp(&cts, &ets, >=)) {
 					error = ETIMEDOUT;
 					break;

Modified: user/davidxu/libthr/sys/sys/_umtx.h
==============================================================================
--- user/davidxu/libthr/sys/sys/_umtx.h	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/sys/sys/_umtx.h	Thu Nov  4 07:53:09 2010	(r214773)
@@ -46,7 +46,8 @@ struct umutex {
 struct ucond {
 	volatile __uint32_t	c_has_waiters;	/* Has waiters in kernel */
 	__uint32_t		c_flags;	/* Flags of the condition variable */
-	__uint32_t		c_spare[2];	/* Spare space */
+	__uint32_t		c_clockid;	/* Clock id */
+	__uint32_t		c_spare[1];	/* Spare space */
 };
 
 struct urwlock {

Modified: user/davidxu/libthr/sys/sys/umtx.h
==============================================================================
--- user/davidxu/libthr/sys/sys/umtx.h	Thu Nov  4 06:51:53 2010	(r214772)
+++ user/davidxu/libthr/sys/sys/umtx.h	Thu Nov  4 07:53:09 2010	(r214773)
@@ -85,6 +85,9 @@
 
 /* flags for UMTX_OP_CV_WAIT */
 #define CVWAIT_CHECK_UNPARKING	0x01
+#define CVWAIT_ABSTIME		0x02
+#define CVWAIT_CLOCKID		0x04
+
 #define UMTX_CHECK_UNPARKING	_CVWAIT_CHECK_UNPARKING
 
 #ifndef _KERNEL



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011040753.oA47r9aI048243>