diff options
author | davidxu <davidxu@FreeBSD.org> | 2012-02-27 13:38:52 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2012-02-27 13:38:52 +0000 |
commit | 96aacc2279b7b65fc0c8ff707abe3d020c1e8378 (patch) | |
tree | 9e46c0856016e3264151a062bf52ebb933fca926 /sys/kern/kern_umtx.c | |
parent | 8a35bc6c4fda7b720a969d6cb7122d1667a826d5 (diff) | |
download | FreeBSD-src-96aacc2279b7b65fc0c8ff707abe3d020c1e8378.zip FreeBSD-src-96aacc2279b7b65fc0c8ff707abe3d020c1e8378.tar.gz |
Follow changes made in revision 232144, pass absolute timeout to kernel,
this eliminates a clock_gettime() syscall.
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r-- | sys/kern/kern_umtx.c | 88 |
1 files changed, 47 insertions, 41 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 790be66..49b015e 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -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 @@ 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, 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); |