Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Feb 2012 13:38:52 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232209 - in head: lib/libthr/thread sys/kern
Message-ID:  <201202271338.q1RDcqEQ020033@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidxu
Date: Mon Feb 27 13:38:52 2012
New Revision: 232209
URL: http://svn.freebsd.org/changeset/base/232209

Log:
  Follow changes made in revision 232144, pass absolute timeout to kernel,
  this eliminates a clock_gettime() syscall.

Modified:
  head/lib/libthr/thread/thr_rwlock.c
  head/lib/libthr/thread/thr_umtx.c
  head/lib/libthr/thread/thr_umtx.h
  head/sys/kern/kern_umtx.c

Modified: head/lib/libthr/thread/thr_rwlock.c
==============================================================================
--- head/lib/libthr/thread/thr_rwlock.c	Mon Feb 27 13:04:09 2012	(r232208)
+++ head/lib/libthr/thread/thr_rwlock.c	Mon Feb 27 13:38:52 2012	(r232209)
@@ -123,7 +123,6 @@ rwlock_rdlock_common(pthread_rwlock_t *r
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
-	struct timespec ts, ts2, *tsp;
 	int flags;
 	int ret;
 
@@ -162,18 +161,8 @@ rwlock_rdlock_common(pthread_rwlock_t *r
 		return (EINVAL);
 
 	for (;;) {
-		if (abstime) {
-			clock_gettime(CLOCK_REALTIME, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
-			if (ts2.tv_sec < 0 || 
-			    (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
-				return (ETIMEDOUT);
-			tsp = &ts2;
-		} else
-			tsp = NULL;
-
 		/* goto kernel and lock it */
-		ret = __thr_rwlock_rdlock(&prwlock->lock, flags, tsp);
+		ret = __thr_rwlock_rdlock(&prwlock->lock, flags, abstime);
 		if (ret != EINTR)
 			break;
 
@@ -255,7 +244,6 @@ rwlock_wrlock_common (pthread_rwlock_t *
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
-	struct timespec ts, ts2, *tsp;
 	int ret;
 
 	CHECK_AND_INIT_RWLOCK
@@ -275,18 +263,8 @@ rwlock_wrlock_common (pthread_rwlock_t *
 		return (EINVAL);
 
 	for (;;) {
-		if (abstime != NULL) {
-			clock_gettime(CLOCK_REALTIME, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
-			if (ts2.tv_sec < 0 || 
-			    (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
-				return (ETIMEDOUT);
-			tsp = &ts2;
-		} else
-			tsp = NULL;
-
 		/* goto kernel and lock it */
-		ret = __thr_rwlock_wrlock(&prwlock->lock, tsp);
+		ret = __thr_rwlock_wrlock(&prwlock->lock, abstime);
 		if (ret == 0) {
 			prwlock->owner = curthread;
 			break;

Modified: head/lib/libthr/thread/thr_umtx.c
==============================================================================
--- head/lib/libthr/thread/thr_umtx.c	Mon Feb 27 13:04:09 2012	(r232208)
+++ head/lib/libthr/thread/thr_umtx.c	Mon Feb 27 13:38:52 2012	(r232209)
@@ -265,15 +265,42 @@ _thr_ucond_broadcast(struct ucond *cv)
 }
 
 int
-__thr_rwlock_rdlock(struct urwlock *rwlock, int flags, struct timespec *tsp)
+__thr_rwlock_rdlock(struct urwlock *rwlock, int flags,
+	const struct timespec *tsp)
 {
-	return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, NULL, tsp);
+	struct _umtx_time timeout, *tm_p;
+	size_t tm_size;
+
+	if (tsp == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._timeout = *tsp;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._clockid = CLOCK_REALTIME;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
+	return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, (void *)tm_size, tm_p);
 }
 
 int
-__thr_rwlock_wrlock(struct urwlock *rwlock, struct timespec *tsp)
+__thr_rwlock_wrlock(struct urwlock *rwlock, const struct timespec *tsp)
 {
-	return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, NULL, tsp);
+	struct _umtx_time timeout, *tm_p;
+	size_t tm_size;
+
+	if (tsp == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._timeout = *tsp;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._clockid = CLOCK_REALTIME;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
+	return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, (void *)tm_size, tm_p);
 }
 
 int

Modified: head/lib/libthr/thread/thr_umtx.h
==============================================================================
--- head/lib/libthr/thread/thr_umtx.h	Mon Feb 27 13:04:09 2012	(r232208)
+++ head/lib/libthr/thread/thr_umtx.h	Mon Feb 27 13:38:52 2012	(r232209)
@@ -60,8 +60,10 @@ void _thr_ucond_init(struct ucond *cv) _
 int _thr_ucond_signal(struct ucond *cv) __hidden;
 int _thr_ucond_broadcast(struct ucond *cv) __hidden;
 
-int __thr_rwlock_rdlock(struct urwlock *rwlock, int flags, struct timespec *tsp) __hidden;
-int __thr_rwlock_wrlock(struct urwlock *rwlock, struct timespec *tsp) __hidden;
+int __thr_rwlock_rdlock(struct urwlock *rwlock, int flags,
+	const struct timespec *tsp) __hidden;
+int __thr_rwlock_wrlock(struct urwlock *rwlock,
+	const struct timespec *tsp) __hidden;
 int __thr_rwlock_unlock(struct urwlock *rwlock) __hidden;
 
 /* Internal used only */

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c	Mon Feb 27 13:04:09 2012	(r232208)
+++ head/sys/kern/kern_umtx.c	Mon Feb 27 13:38:52 2012	(r232209)
@@ -2289,7 +2289,6 @@ do_cv_wait(struct thread *td, struct uco
 	struct timespec *timeout, u_long wflags)
 {
 	struct umtx_q *uq;
-	struct timeval tv;
 	struct timespec cts, ets, tts;
 	uint32_t flags;
 	uint32_t clockid;
@@ -2345,9 +2344,8 @@ do_cv_wait(struct thread *td, struct uco
 				kern_clock_gettime(td, clockid, &cts);
 				timespecsub(&tts, &cts);
 			}
-			TIMESPEC_TO_TIMEVAL(&tv, &tts);
 			for (;;) {
-				error = umtxq_sleep(uq, "ucond", tvtohz(&tv));
+				error = umtxq_sleep(uq, "ucond", tstohz(&tts));
 				if (error != ETIMEDOUT)
 					break;
 				kern_clock_gettime(td, clockid, &cts);
@@ -2357,7 +2355,6 @@ do_cv_wait(struct thread *td, struct uco
 				}
 				tts = ets;
 				timespecsub(&tts, &cts);
-				TIMESPEC_TO_TIMEVAL(&tv, &tts);
 			}
 		}
 	}
@@ -2555,27 +2552,30 @@ sleep:
 }
 
 static int
-do_rw_rdlock2(struct thread *td, void *obj, long val, struct timespec *timeout)
+do_rw_rdlock2(struct thread *td, void *obj, long val, struct _umtx_time *timeout)
 {
-	struct timespec ts, ts2, ts3;
-	struct timeval tv;
+	struct timespec cts, ets, tts;
 	int error;
 
-	getnanouptime(&ts);
-	timespecadd(&ts, timeout);
-	TIMESPEC_TO_TIMEVAL(&tv, timeout);
+	kern_clock_gettime(td, timeout->_clockid, &cts);
+	if ((timeout->_flags & UMTX_ABSTIME) == 0) {
+		ets = cts;
+		timespecadd(&ets, &timeout->_timeout);
+		tts = timeout->_timeout;
+	} else {
+		ets = timeout->_timeout;
+		tts = timeout->_timeout;
+		timespecsub(&tts, &cts);
+	}
 	for (;;) {
-		error = do_rw_rdlock(td, obj, val, tvtohz(&tv));
+		error = do_rw_rdlock(td, obj, val, tstohz(&tts));
 		if (error != ETIMEDOUT)
 			break;
-		getnanouptime(&ts2);
-		if (timespeccmp(&ts2, &ts, >=)) {
-			error = ETIMEDOUT;
+		kern_clock_gettime(td, timeout->_clockid, &cts);
+		if (timespeccmp(&cts, &ets, >=))
 			break;
-		}
-		ts3 = ts;
-		timespecsub(&ts3, &ts2);
-		TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+		tts = ets;
+		timespecsub(&tts, &cts);
 	}
 	if (error == ERESTART)
 		error = EINTR;
@@ -2692,27 +2692,30 @@ sleep:
 }
 
 static int
-do_rw_wrlock2(struct thread *td, void *obj, struct timespec *timeout)
+do_rw_wrlock2(struct thread *td, void *obj, struct _umtx_time *timeout)
 {
-	struct timespec ts, ts2, ts3;
-	struct timeval tv;
+	struct timespec cts, ets, tts;
 	int error;
 
-	getnanouptime(&ts);
-	timespecadd(&ts, timeout);
-	TIMESPEC_TO_TIMEVAL(&tv, timeout);
+	kern_clock_gettime(td, timeout->_clockid, &cts);
+	if ((timeout->_flags & UMTX_ABSTIME) == 0) {
+		ets = cts;
+		timespecadd(&ets, &timeout->_timeout);
+		tts = timeout->_timeout;
+	} else {
+		ets = timeout->_timeout;
+		tts = timeout->_timeout;
+		timespecsub(&tts, &cts);
+	}
 	for (;;) {
-		error = do_rw_wrlock(td, obj, tvtohz(&tv));
+		error = do_rw_wrlock(td, obj, tstohz(&tts));
 		if (error != ETIMEDOUT)
 			break;
-		getnanouptime(&ts2);
-		if (timespeccmp(&ts2, &ts, >=)) {
-			error = ETIMEDOUT;
+		kern_clock_gettime(td, timeout->_clockid, &cts);
+		if (timespeccmp(&cts, &ets, >=))
 			break;
-		}
-		ts3 = ts;
-		timespecsub(&ts3, &ts2);
-		TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+		tts = ets;
+		timespecsub(&tts, &cts);
 	}
 	if (error == ERESTART)
 		error = EINTR;
@@ -3159,14 +3162,15 @@ __umtx_op_cv_broadcast(struct thread *td
 static int
 __umtx_op_rw_rdlock(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec timeout;
+	struct _umtx_time timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL) {
 		error = do_rw_rdlock(td, uap->obj, uap->val, 0);
 	} else {
-		error = umtx_copyin_timeout(uap->uaddr2, &timeout);
+		error = umtx_copyin_umtx_time(uap->uaddr2,
+		   (size_t)uap->uaddr1, &timeout);
 		if (error != 0)
 			return (error);
 		error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout);
@@ -3177,14 +3181,15 @@ __umtx_op_rw_rdlock(struct thread *td, s
 static int
 __umtx_op_rw_wrlock(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec timeout;
+	struct _umtx_time timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL) {
 		error = do_rw_wrlock(td, uap->obj, 0);
 	} else {
-		error = umtx_copyin_timeout(uap->uaddr2, &timeout);
+		error = umtx_copyin_umtx_time(uap->uaddr2, 
+		   (size_t)uap->uaddr1, &timeout);
 		if (error != 0)
 			return (error);
 
@@ -3430,14 +3435,15 @@ __umtx_op_cv_wait_compat32(struct thread
 static int
 __umtx_op_rw_rdlock_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec timeout;
+	struct _umtx_time timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL) {
 		error = do_rw_rdlock(td, uap->obj, uap->val, 0);
 	} else {
-		error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
+		error = umtx_copyin_umtx_time32(uap->uaddr2,
+		    (size_t)uap->uaddr1, &timeout);
 		if (error != 0)
 			return (error);
 		error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout);
@@ -3448,17 +3454,17 @@ __umtx_op_rw_rdlock_compat32(struct thre
 static int
 __umtx_op_rw_wrlock_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec timeout;
+	struct _umtx_time timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL) {
 		error = do_rw_wrlock(td, uap->obj, 0);
 	} else {
-		error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
+		error = umtx_copyin_umtx_time32(uap->uaddr2,
+		    (size_t)uap->uaddr1, &timeout);
 		if (error != 0)
 			return (error);
-
 		error = do_rw_wrlock2(td, uap->obj, &timeout);
 	}
 	return (error);



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