Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Feb 2012 02:12:17 +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: r232144 - in head: lib/libc/gen lib/libthr/thread sys/kern sys/sys
Message-ID:  <201202250212.q1P2CH7Y094426@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidxu
Date: Sat Feb 25 02:12:17 2012
New Revision: 232144
URL: http://svn.freebsd.org/changeset/base/232144

Log:
  In revision 231989, we pass a 16-bit clock ID into kernel, however
  according to POSIX document, the clock ID may be dynamically allocated,
  it unlikely will be in 64K forever. To make it future compatible, we
  pack all timeout information into a new structure called _umtx_time, and
  use fourth argument as a size indication, a zero means it is old code
  using timespec as timeout value, but the new structure also includes flags
  and a clock ID, so the size argument is different than before, and it is
  non-zero. With this change, it is possible that a thread can sleep
  on any supported clock, though current kernel code does not have such a
  POSIX clock driver system.

Modified:
  head/lib/libc/gen/sem.c
  head/lib/libc/gen/sem_new.c
  head/lib/libthr/thread/thr_umtx.c
  head/sys/kern/kern_umtx.c
  head/sys/sys/_umtx.h
  head/sys/sys/umtx.h

Modified: head/lib/libc/gen/sem.c
==============================================================================
--- head/lib/libc/gen/sem.c	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/lib/libc/gen/sem.c	Sat Feb 25 02:12:17 2012	(r232144)
@@ -312,15 +312,24 @@ _libc_sem_unlink_compat(const char *name
 }
 
 static int
-_umtx_wait_uint(volatile unsigned *mtx, unsigned id, const struct timespec *timeout)
+_umtx_wait_uint(volatile unsigned *mtx, unsigned id, const struct timespec *abstime)
 {
-	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
-	    timeout->tv_nsec <= 0))) {
-		errno = ETIMEDOUT;
-		return (-1);
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
+
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._clockid = CLOCK_REALTIME;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
 	}
 	return _umtx_op(__DEVOLATILE(void *, mtx),
-		UMTX_OP_WAIT_UINT_PRIVATE, id, NULL, __DECONST(void*, timeout));
+		UMTX_OP_WAIT_UINT_PRIVATE, id, 
+		(void *)tm_size, __DECONST(void*, tm_p));
 }
 
 static int
@@ -355,7 +364,6 @@ int
 _libc_sem_timedwait_compat(sem_t * __restrict sem,
 	const struct timespec * __restrict abstime)
 {
-	struct timespec ts, ts2;
 	int val, retval;
 
 	if (sem_check_validity(sem) != 0)
@@ -384,13 +392,11 @@ _libc_sem_timedwait_compat(sem_t * __res
 				errno = EINVAL;
 				return (-1);
 			}
-			clock_gettime(CLOCK_REALTIME, &ts);
-	                TIMESPEC_SUB(&ts2, abstime, &ts);
 		}
 		atomic_add_int(&(*sem)->nwaiters, 1);
 		pthread_cleanup_push(sem_cancel_handler, sem);
 		_pthread_cancel_enter(1);
-		retval = _umtx_wait_uint(&(*sem)->count, 0, abstime ? &ts2 : NULL);
+		retval = _umtx_wait_uint(&(*sem)->count, 0, abstime);
 		_pthread_cancel_leave(0);
 		pthread_cleanup_pop(0);
 		atomic_add_int(&(*sem)->nwaiters, -1);

Modified: head/lib/libc/gen/sem_new.c
==============================================================================
--- head/lib/libc/gen/sem_new.c	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/lib/libc/gen/sem_new.c	Sat Feb 25 02:12:17 2012	(r232144)
@@ -339,15 +339,23 @@ usem_wake(struct _usem *sem)
 }
 
 static __inline int
-usem_wait(struct _usem *sem, const struct timespec *timeout)
+usem_wait(struct _usem *sem, const struct timespec *abstime)
 {
-	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
-	    timeout->tv_nsec <= 0))) {
-		errno = ETIMEDOUT;
-		return (-1);
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
+
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._clockid = CLOCK_REALTIME;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
 	}
-	return _umtx_op(sem, UMTX_OP_SEM_WAIT, 0, NULL,
-			__DECONST(void*, timeout));
+	return _umtx_op(sem, UMTX_OP_SEM_WAIT, 0, 
+		    (void *)tm_size, __DECONST(void*, tm_p));
 }
 
 int
@@ -381,7 +389,6 @@ int
 _sem_timedwait(sem_t * __restrict sem,
 	const struct timespec * __restrict abstime)
 {
-	struct timespec ts, ts2;
 	int val, retval;
 
 	if (sem_check_validity(sem) != 0)
@@ -408,11 +415,9 @@ _sem_timedwait(sem_t * __restrict sem,
 				errno = EINVAL;
 				return (-1);
 			}
-			clock_gettime(CLOCK_REALTIME, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
 		}
 		_pthread_cancel_enter(1);
-		retval = usem_wait(&sem->_kern, abstime ? &ts2 : NULL);
+		retval = usem_wait(&sem->_kern, abstime);
 		_pthread_cancel_leave(0);
 	}
 	return (retval);

Modified: head/lib/libthr/thread/thr_umtx.c
==============================================================================
--- head/lib/libthr/thread/thr_umtx.c	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/lib/libthr/thread/thr_umtx.c	Sat Feb 25 02:12:17 2012	(r232144)
@@ -109,23 +109,30 @@ __thr_umutex_lock_spin(struct umutex *mt
 
 int
 __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
-	const struct timespec *ets)
+	const struct timespec *abstime)
 {
-	struct timespec timo, cts;
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
 	uint32_t owner;
 	int ret;
 
-	clock_gettime(CLOCK_REALTIME, &cts);
-	TIMESPEC_SUB(&timo, ets, &cts);
-
-	if (timo.tv_sec < 0)
-		return (ETIMEDOUT);
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._clockid = CLOCK_REALTIME;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
 
 	for (;;) {
 		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, 0,
+				 (void *)tm_size, __DECONST(void *, tm_p));
 
 			/* now try to lock it */
 			owner = mtx->m_owner;
@@ -133,18 +140,13 @@ __thr_umutex_timedlock(struct umutex *mt
 			     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, 0, 
+				 (void *)tm_size, __DECONST(void *, tm_p));
 			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);
 }
@@ -200,10 +202,23 @@ int
 _thr_umtx_timedwait_uint(volatile u_int *mtx, u_int id, int clockid,
 	const struct timespec *abstime, int shared)
 {
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
+
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._clockid = CLOCK_REALTIME;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
+
 	return _umtx_op_err(__DEVOLATILE(void *, mtx), 
 		shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 
-	       	abstime != NULL ? (void *)(uintptr_t)((clockid << 16) | UMTX_WAIT_ABSTIME) : 0, 
-		__DECONST(void *, abstime));
+		(void *)tm_size, __DECONST(void *, tm_p));
 }
 
 int

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/sys/kern/kern_umtx.c	Sat Feb 25 02:12:17 2012	(r232144)
@@ -984,12 +984,11 @@ tstohz(const struct timespec *tsp)
  */
 static int
 do_wait(struct thread *td, void *addr, u_long id,
-	struct timespec *timeout, int compat32, int is_private, uint32_t flags)
+	struct _umtx_time *timeout, int compat32, int is_private)
 {
 	struct umtx_q *uq;
 	struct timespec ets, cts, tts;
 	u_long tmp;
-	int clockid = (flags >> 16) & 0xFFFF;
 	int error = 0;
 
 	uq = td->td_umtxq;
@@ -1014,12 +1013,12 @@ do_wait(struct thread *td, void *addr, u
 		umtxq_remove(uq);
 		umtxq_unlock(&uq->uq_key);
 	} else {
-		kern_clock_gettime(td, clockid, &cts);
-		if ((flags & UMTX_WAIT_ABSTIME) == 0) {
+		kern_clock_gettime(td, timeout->_clockid, &cts);
+		if ((timeout->_flags & UMTX_ABSTIME) == 0) {
 			ets = cts;
-			timespecadd(&ets, timeout);
+			timespecadd(&ets, &timeout->_timeout);
 		} else {
-			ets = *timeout;
+			ets = timeout->_timeout;
 		}
 		umtxq_lock(&uq->uq_key);
 		for (;;) {
@@ -1037,7 +1036,7 @@ do_wait(struct thread *td, void *addr, u
 			if (error != ETIMEDOUT)
 				break;
 			umtxq_unlock(&uq->uq_key);
-			kern_clock_gettime(td, clockid, &cts);
+			kern_clock_gettime(td, timeout->_clockid, &cts);
 			umtxq_lock(&uq->uq_key);
 		}
 		umtxq_remove(uq);
@@ -2218,10 +2217,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 _umtx_time *timeout, int mode)
 {
-	struct timespec ts, ts2, ts3;
-	struct timeval tv;
+	struct timespec cts, ets, tts;
 	uint32_t flags;
 	int error;
 
@@ -2235,21 +2233,25 @@ 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);
+		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_lock_umutex(td, m, flags, tvtohz(&tv), mode);
+			error = _do_lock_umutex(td, m, flags, tstohz(&tts), mode);
 			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);
 		}
 		/* Timed-locking is not restarted. */
 		if (error == ERESTART)
@@ -2797,10 +2799,9 @@ out:
 }
 
 static int
-do_sem_wait(struct thread *td, struct _usem *sem, struct timespec *timeout)
+do_sem_wait(struct thread *td, struct _usem *sem, struct _umtx_time *timeout)
 {
 	struct umtx_q *uq;
-	struct timeval tv;
 	struct timespec cts, ets, tts;
 	uint32_t flags, count;
 	int error;
@@ -2829,27 +2830,32 @@ do_sem_wait(struct thread *td, struct _u
 
 	umtxq_lock(&uq->uq_key);
 	umtxq_unbusy(&uq->uq_key);
-	umtxq_unlock(&uq->uq_key);
 
-	umtxq_lock(&uq->uq_key);
 	if (timeout == NULL) {
 		error = umtxq_sleep(uq, "usem", 0);
 	} else {
-		getnanouptime(&ets);
-		timespecadd(&ets, timeout);
-		TIMESPEC_TO_TIMEVAL(&tv, timeout);
+		umtxq_unlock(&uq->uq_key);
+		kern_clock_gettime(td, timeout->_clockid, &cts);
+		if ((timeout->_flags & UMTX_ABSTIME) == 0) {
+			ets = cts;
+			timespecadd(&ets, &timeout->_timeout);
+		} else {
+			ets = timeout->_timeout;
+		}
+		umtxq_lock(&uq->uq_key);
 		for (;;) {
-			error = umtxq_sleep(uq, "usem", tvtohz(&tv));
-			if (error != ETIMEDOUT)
-				break;
-			getnanouptime(&cts);
 			if (timespeccmp(&cts, &ets, >=)) {
 				error = ETIMEDOUT;
 				break;
 			}
 			tts = ets;
 			timespecsub(&tts, &cts);
-			TIMESPEC_TO_TIMEVAL(&tv, &tts);
+			error = umtxq_sleep(uq, "usem", tstohz(&tts));
+			if (error != ETIMEDOUT)
+				break;
+			umtxq_unlock(&uq->uq_key);
+			kern_clock_gettime(td, timeout->_clockid, &cts);
+			umtxq_lock(&uq->uq_key);
 		}
 	}
 
@@ -2923,6 +2929,25 @@ umtx_copyin_timeout(const void *addr, st
 	return (error);
 }
 
+static inline int
+umtx_copyin_umtx_time(const void *addr, size_t size, struct _umtx_time *tp)
+{
+	int error;
+	
+	tp->_clockid = CLOCK_REALTIME;
+	tp->_flags   = 0;
+	if (size <= sizeof(struct timespec))
+		error = copyin(addr, &tp->_timeout, sizeof(struct timespec));
+	else 
+		error = copyin(addr, tp, sizeof(struct _umtx_time));
+	if (error != 0)
+		return (error);
+	if (tp->_timeout.tv_sec < 0 ||
+	    tp->_timeout.tv_nsec >= 1000000000 || tp->_timeout.tv_nsec < 0)
+		return (EINVAL);
+	return (0);
+}
+
 static int
 __umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap)
 {
@@ -2950,58 +2975,55 @@ __umtx_op_unlock_umtx(struct thread *td,
 static int
 __umtx_op_wait(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time timeout, *tm_p;
 	int error;
-	uint32_t flags;
 
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	flags = (uint32_t)(uintptr_t)uap->uaddr1;
-	return do_wait(td, uap->obj, uap->val, ts, 0, 0, flags);
+	return do_wait(td, uap->obj, uap->val, tm_p, 0, 0);
 }
 
 static int
 __umtx_op_wait_uint(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time timeout, *tm_p;
 	int error;
-	uint32_t flags;
 
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	flags = (uint32_t)(uintptr_t)uap->uaddr1;
-	return do_wait(td, uap->obj, uap->val, ts, 1, 0, flags);
+	return do_wait(td, uap->obj, uap->val, tm_p, 1, 0);
 }
 
 static int
 __umtx_op_wait_uint_private(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
-	uint32_t flags;
 
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	flags = (uint32_t)(uintptr_t)uap->uaddr1;
-	return do_wait(td, uap->obj, uap->val, ts, 1, 1, flags);
+	return do_wait(td, uap->obj, uap->val, tm_p, 1, 1);
 }
 
 static int
@@ -3045,19 +3067,20 @@ __umtx_op_wake_private(struct thread *td
 static int
 __umtx_op_lock_umutex(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, 0);
+	return do_lock_umutex(td, uap->obj, tm_p, 0);
 }
 
 static int
@@ -3069,19 +3092,20 @@ __umtx_op_trylock_umutex(struct thread *
 static int
 __umtx_op_wait_umutex(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
+	return do_lock_umutex(td, uap->obj, tm_p, _UMUTEX_WAIT);
 }
 
 static int
@@ -3178,19 +3202,20 @@ __umtx_op_rw_unlock(struct thread *td, s
 static int
 __umtx_op_sem_wait(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return (do_sem_wait(td, uap->obj, ts));
+	return (do_sem_wait(td, uap->obj, tm_p));
 }
 
 static int
@@ -3254,6 +3279,12 @@ struct timespec32 {
 	uint32_t tv_nsec;
 };
 
+struct umtx_time32 {
+	struct	timespec32	timeout;
+	uint32_t		flags;
+	uint32_t		clockid;
+};
+
 static inline int
 umtx_copyin_timeout32(void *addr, struct timespec *tsp)
 {
@@ -3274,6 +3305,30 @@ umtx_copyin_timeout32(void *addr, struct
 	return (error);
 }
 
+static inline int
+umtx_copyin_umtx_time32(const void *addr, size_t size, struct _umtx_time *tp)
+{
+	struct umtx_time32 t32;
+	int error;
+	
+	t32.clockid = CLOCK_REALTIME;
+	t32.flags   = 0;
+	if (size <= sizeof(struct timespec32))
+		error = copyin(addr, &t32.timeout, sizeof(struct timespec32));
+	else 
+		error = copyin(addr, &t32, sizeof(struct umtx_time32));
+	if (error != 0)
+		return (error);
+	if (t32.timeout.tv_sec < 0 ||
+	    t32.timeout.tv_nsec >= 1000000000 || t32.timeout.tv_nsec < 0)
+		return (EINVAL);
+	tp->_timeout.tv_sec = t32.timeout.tv_sec;
+	tp->_timeout.tv_nsec = t32.timeout.tv_nsec;
+	tp->_flags = t32.flags;
+	tp->_clockid = t32.clockid;
+	return (0);
+}
+
 static int
 __umtx_op_lock_umtx_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
@@ -3301,56 +3356,57 @@ __umtx_op_unlock_umtx_compat32(struct th
 static int
 __umtx_op_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
-	uint32_t flags;
 
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	flags = (uint32_t)(uintptr_t)uap->uaddr1;
-	return do_wait(td, uap->obj, uap->val, ts, 1, 0, flags);
+	return do_wait(td, uap->obj, uap->val, tm_p, 1, 0);
 }
 
 static int
 __umtx_op_lock_umutex_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	else {
-		error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
+		error = umtx_copyin_umtx_time(uap->uaddr2,
+			    (size_t)uap->uaddr1, &timeout);
 		if (error != 0)
 			return (error);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, 0);
+	return do_lock_umutex(td, uap->obj, tm_p, 0);
 }
 
 static int
 __umtx_op_wait_umutex_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
+	return do_lock_umutex(td, uap->obj, tm_p, _UMUTEX_WAIT);
 }
 
 static int
@@ -3411,38 +3467,38 @@ __umtx_op_rw_wrlock_compat32(struct thre
 static int
 __umtx_op_wait_uint_private_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
-	uint32_t flags;
 
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	flags = (uint32_t)(uintptr_t)uap->uaddr1;
-	return do_wait(td, uap->obj, uap->val, ts, 1, 1, flags);
+	return do_wait(td, uap->obj, uap->val, tm_p, 1, 1);
 }
 
 static int
 __umtx_op_sem_wait_compat32(struct thread *td, struct _umtx_op_args *uap)
 {
-	struct timespec *ts, timeout;
+	struct _umtx_time *tm_p, timeout;
 	int error;
 
 	/* Allow a null timespec (wait forever). */
 	if (uap->uaddr2 == NULL)
-		ts = NULL;
+		tm_p = NULL;
 	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);
-		ts = &timeout;
+		tm_p = &timeout;
 	}
-	return (do_sem_wait(td, uap->obj, ts));
+	return (do_sem_wait(td, uap->obj, tm_p));
 }
 
 static int

Modified: head/sys/sys/_umtx.h
==============================================================================
--- head/sys/sys/_umtx.h	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/sys/sys/_umtx.h	Sat Feb 25 02:12:17 2012	(r232144)
@@ -31,6 +31,7 @@
 #define	_SYS__UMTX_H_
 
 #include <sys/_types.h>
+#include <sys/_timespec.h>
 
 struct umtx {
 	volatile unsigned long	u_owner;	/* Owner of the mutex. */
@@ -64,4 +65,10 @@ struct _usem {
 	__uint32_t		_flags;
 };
 
+struct _umtx_time {
+	struct timespec		_timeout;
+	__uint32_t		_flags;
+	__uint32_t		_clockid;
+};
+
 #endif /* !_SYS__UMTX_H_ */

Modified: head/sys/sys/umtx.h
==============================================================================
--- head/sys/sys/umtx.h	Sat Feb 25 01:33:39 2012	(r232143)
+++ head/sys/sys/umtx.h	Sat Feb 25 02:12:17 2012	(r232144)
@@ -87,7 +87,7 @@
 #define	CVWAIT_ABSTIME		0x02
 #define	CVWAIT_CLOCKID		0x04
 
-#define	UMTX_WAIT_ABSTIME	0x01
+#define	UMTX_ABSTIME		0x01
 
 #define	UMTX_CHECK_UNPARKING	CVWAIT_CHECK_UNPARKING
 



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