Follow changes made in revision 232144, pass absolute timeout to kernel,
this eliminates a clock_gettime() syscall.
This commit is contained in:
parent
8a35bc6c4f
commit
96aacc2279
@ -123,7 +123,6 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
|
||||
{
|
||||
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 *rwlock, const struct timespec *abstime)
|
||||
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 *rwlock, const struct timespec *abstime)
|
||||
{
|
||||
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 *rwlock, const struct timespec *abstime)
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -60,8 +60,10 @@ void _thr_ucond_init(struct ucond *cv) __hidden;
|
||||
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 */
|
||||
|
@ -2289,7 +2289,6 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
|
||||
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 ucond *cv, struct umutex *m,
|
||||
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 ucond *cv, struct umutex *m,
|
||||
}
|
||||
tts = ets;
|
||||
timespecsub(&tts, &cts);
|
||||
TIMESPEC_TO_TIMEVAL(&tv, &tts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2555,27 +2552,30 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock, long fflag, int timo)
|
||||
}
|
||||
|
||||
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 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock, int timo)
|
||||
}
|
||||
|
||||
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, struct _umtx_op_args *uap)
|
||||
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, struct _umtx_op_args *uap)
|
||||
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 *td, struct _umtx_op_args *uap)
|
||||
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 thread *td, struct _umtx_op_args *uap)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user