svn commit: r214775 - in user/davidxu/libthr: lib/libthr/thread sys/kern sys/sys

David Xu davidxu at FreeBSD.org
Thu Nov 4 08:58:16 UTC 2010


Author: davidxu
Date: Thu Nov  4 08:58:16 2010
New Revision: 214775
URL: http://svn.freebsd.org/changeset/base/214775

Log:
  Introduce UMUTEX_ABSTIME option, so we can reduce a clock_gettime
  syscall in userland.

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

Modified: user/davidxu/libthr/lib/libthr/thread/thr_umtx.c
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_umtx.c	Thu Nov  4 08:51:45 2010	(r214774)
+++ user/davidxu/libthr/lib/libthr/thread/thr_umtx.c	Thu Nov  4 08:58:16 2010	(r214775)
@@ -66,7 +66,8 @@ __thr_umutex_lock(struct umutex *mtx, ui
 
 			owner = mtx->m_owner;
 			if ((owner & ~UMUTEX_CONTESTED) == 0 &&
-			     atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
+			     atomic_cmpset_acq_32(&mtx->m_owner, owner,
+				id|owner))
 				return (0);
 		}
 	}
@@ -78,40 +79,32 @@ int
 __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
 	const struct timespec *ets)
 {
-	struct timespec timo, cts;
 	uint32_t owner;
 	int ret;
 
-	clock_gettime(CLOCK_REALTIME, &cts);
-	TIMESPEC_SUB(&timo, ets, &cts);
-
-	if (timo.tv_sec < 0)
-		return (ETIMEDOUT);
-
 	for (;;) {
-		if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
+		if ((mtx->m_flags &
+		     (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
 
 			/* wait in kernel */
-			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0, 0, &timo);
+			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT,
+				UMUTEX_ABSTIME, NULL, __DECONST(void*, ets));
 
 			/* now try to lock it */
 			owner = mtx->m_owner;
 			if ((owner & ~UMUTEX_CONTESTED) == 0 &&
-			     atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
+			    atomic_cmpset_acq_32(&mtx->m_owner, owner,
+				 id|owner)) {
 				return (0);
+			}
 		} else {
-			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, &timo);
+			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK,
+				UMUTEX_ABSTIME, NULL, __DECONST(void *, ets));
 			if (ret == 0)
 				break;
 		}
 		if (ret == ETIMEDOUT)
 			break;
-		clock_gettime(CLOCK_REALTIME, &cts);
-		TIMESPEC_SUB(&timo, ets, &cts);
-		if (timo.tv_sec < 0 || (timo.tv_sec == 0 && timo.tv_nsec == 0)) {
-			ret = ETIMEDOUT;
-			break;
-		}
 	}
 	return (ret);
 }
@@ -122,7 +115,8 @@ __thr_umutex_unlock(struct umutex *mtx, 
 #ifndef __ia64__
 	/* XXX this logic has a race-condition on ia64. */
 	if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
-		atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED, UMUTEX_CONTESTED);
+		atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED,
+		    UMUTEX_CONTESTED);
 		return _umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE, 0, 0, 0);
 	}
 #endif /* __ia64__ */
@@ -159,15 +153,16 @@ _thr_umtx_wait_uint(volatile u_int *mtx,
 		timeout->tv_nsec <= 0)))
 		return (ETIMEDOUT);
 	return _umtx_op_err(__DEVOLATILE(void *, mtx), 
-			shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 0,
+		shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 0,
 			__DECONST(void*, timeout));
 }
 
 int
 _thr_umtx_wake(volatile void *mtx, int nr_wakeup, int shared)
 {
-	return _umtx_op_err(__DEVOLATILE(void *, mtx), shared ? UMTX_OP_WAKE : UMTX_OP_WAKE_PRIVATE,
-		nr_wakeup, 0, 0);
+	return _umtx_op_err(__DEVOLATILE(void *, mtx),
+		 shared ? UMTX_OP_WAKE : UMTX_OP_WAKE_PRIVATE,
+		 nr_wakeup, 0, 0);
 }
 
 void

Modified: user/davidxu/libthr/sys/kern/kern_umtx.c
==============================================================================
--- user/davidxu/libthr/sys/kern/kern_umtx.c	Thu Nov  4 08:51:45 2010	(r214774)
+++ user/davidxu/libthr/sys/kern/kern_umtx.c	Thu Nov  4 08:58:16 2010	(r214775)
@@ -2369,9 +2369,9 @@ _do_lock_umutex(struct thread *td, struc
  */
 static int
 do_lock_umutex(struct thread *td, struct umutex *m,
-	struct timespec *timeout, int mode)
+	struct timespec *timeout, int mode, int wflags)
 {
-	struct timespec ts, ts2, ts3;
+	struct timespec cts, ets, tts;
 	struct timeval tv;
 	uint32_t flags;
 	int error;
@@ -2386,21 +2386,30 @@ do_lock_umutex(struct thread *td, struct
 		if (error == EINTR && mode != _UMUTEX_WAIT)
 			error = ERESTART;
 	} else {
-		getnanouptime(&ts);
-		timespecadd(&ts, timeout);
-		TIMESPEC_TO_TIMEVAL(&tv, timeout);
+		const clockid_t clockid = CLOCK_REALTIME;
+		if ((wflags & UMUTEX_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 = _do_lock_umutex(td, m, flags, tvtohz(&tv), mode);
 			if (error != ETIMEDOUT)
 				break;
-			getnanouptime(&ts2);
-			if (timespeccmp(&ts2, &ts, >=)) {
+			kern_clock_gettime(td, clockid, &cts);
+			if (timespeccmp(&cts, &ets, >=)) {
 				error = ETIMEDOUT;
 				break;
 			}
-			ts3 = ts;
-			timespecsub(&ts3, &ts2);
-			TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+			tts = ets;
+			timespecsub(&tts, &cts);
+			TIMESPEC_TO_TIMEVAL(&tv, &tts);
 		}
 		/* Timed-locking is not restarted. */
 		if (error == ERESTART)
@@ -3513,13 +3522,13 @@ __umtx_op_lock_umutex(struct thread *td,
 		}
 		ts = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, 0);
+	return do_lock_umutex(td, uap->obj, ts, 0, uap->val);
 }
 
 static int
 __umtx_op_trylock_umutex(struct thread *td, struct _umtx_op_args *uap)
 {
-	return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY);
+	return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY, 0);
 }
 
 static int
@@ -3542,7 +3551,7 @@ __umtx_op_wait_umutex(struct thread *td,
 		}
 		ts = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
+	return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT, uap->val);
 }
 
 static int

Modified: user/davidxu/libthr/sys/sys/umtx.h
==============================================================================
--- user/davidxu/libthr/sys/sys/umtx.h	Thu Nov  4 08:51:45 2010	(r214774)
+++ user/davidxu/libthr/sys/sys/umtx.h	Thu Nov  4 08:58:16 2010	(r214775)
@@ -83,6 +83,9 @@
 #define	UMTX_OP_SEM_WAKE	20
 #define	UMTX_OP_MAX		21
 
+/* flags for UMUTEX_LOCK */
+#define UMUTEX_ABSTIME		0x01
+
 /* flags for UMTX_OP_CV_WAIT */
 #define CVWAIT_CHECK_UNPARKING	0x01
 #define CVWAIT_ABSTIME		0x02


More information about the svn-src-user mailing list