aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/sem.c26
-rw-r--r--lib/libc/gen/sem_new.c27
-rw-r--r--lib/libthr/thread/thr_umtx.c49
-rw-r--r--sys/kern/kern_umtx.c252
-rw-r--r--sys/sys/_umtx.h7
-rw-r--r--sys/sys/umtx.h2
6 files changed, 226 insertions, 137 deletions
diff --git a/lib/libc/gen/sem.c b/lib/libc/gen/sem.c
index 842298f4d2a3..71cd0517743d 100644
--- a/lib/libc/gen/sem.c
+++ b/lib/libc/gen/sem.c
@@ -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 * __restrict sem,
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);
diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c
index 1480afb3a6c2..af64310c6d8f 100644
--- a/lib/libc/gen/sem_new.c
+++ b/lib/libc/gen/sem_new.c
@@ -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);
diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c
index f7acac395756..38c3b042b2af 100644
--- a/lib/libthr/thread/thr_umtx.c
+++ b/lib/libthr/thread/thr_umtx.c
@@ -109,23 +109,30 @@ __thr_umutex_lock_spin(struct umutex *mtx, uint32_t id)
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 *mtx, uint32_t id,
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
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 2ef8d953f54f..790be668bdc9 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -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_long id,
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_long id,
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, struct umutex *m, int flags, int timo,
*/
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 umutex *m,
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 _usem *sem, struct timespec *timeout)
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, struct timespec *tsp)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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 *td, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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 timespec *tsp)
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 thread *td, struct _umtx_op_args *uap)
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 thread *td, struct _umtx_op_args *uap)
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
diff --git a/sys/sys/_umtx.h b/sys/sys/_umtx.h
index fa0ed99280b7..20a651064076 100644
--- a/sys/sys/_umtx.h
+++ b/sys/sys/_umtx.h
@@ -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_ */
diff --git a/sys/sys/umtx.h b/sys/sys/umtx.h
index cfdb56561166..aa90629be33f 100644
--- a/sys/sys/umtx.h
+++ b/sys/sys/umtx.h
@@ -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