svn commit: r214775 - in user/davidxu/libthr: lib/libthr/thread
sys/kern sys/sys
David Xu
davidxu at FreeBSD.org
Thu Nov 4 08:58:16 UTC 2010
Author: davidxu
Date: Thu Nov 4 08:58:16 2010
New Revision: 214775
URL: http://svn.freebsd.org/changeset/base/214775
Log:
Introduce UMUTEX_ABSTIME option, so we can reduce a clock_gettime
syscall in userland.
Modified:
user/davidxu/libthr/lib/libthr/thread/thr_umtx.c
user/davidxu/libthr/sys/kern/kern_umtx.c
user/davidxu/libthr/sys/sys/umtx.h
Modified: user/davidxu/libthr/lib/libthr/thread/thr_umtx.c
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_umtx.c Thu Nov 4 08:51:45 2010 (r214774)
+++ user/davidxu/libthr/lib/libthr/thread/thr_umtx.c Thu Nov 4 08:58:16 2010 (r214775)
@@ -66,7 +66,8 @@ __thr_umutex_lock(struct umutex *mtx, ui
owner = mtx->m_owner;
if ((owner & ~UMUTEX_CONTESTED) == 0 &&
- atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
+ atomic_cmpset_acq_32(&mtx->m_owner, owner,
+ id|owner))
return (0);
}
}
@@ -78,40 +79,32 @@ int
__thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
const struct timespec *ets)
{
- struct timespec timo, cts;
uint32_t owner;
int ret;
- clock_gettime(CLOCK_REALTIME, &cts);
- TIMESPEC_SUB(&timo, ets, &cts);
-
- if (timo.tv_sec < 0)
- return (ETIMEDOUT);
-
for (;;) {
- if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
+ 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,
+ UMUTEX_ABSTIME, NULL, __DECONST(void*, ets));
/* now try to lock it */
owner = mtx->m_owner;
if ((owner & ~UMUTEX_CONTESTED) == 0 &&
- atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
+ 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,
+ UMUTEX_ABSTIME, NULL, __DECONST(void *, ets));
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);
}
@@ -122,7 +115,8 @@ __thr_umutex_unlock(struct umutex *mtx,
#ifndef __ia64__
/* XXX this logic has a race-condition on ia64. */
if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
- atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED, UMUTEX_CONTESTED);
+ atomic_cmpset_rel_32(&mtx->m_owner, id | UMUTEX_CONTESTED,
+ UMUTEX_CONTESTED);
return _umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE, 0, 0, 0);
}
#endif /* __ia64__ */
@@ -159,15 +153,16 @@ _thr_umtx_wait_uint(volatile u_int *mtx,
timeout->tv_nsec <= 0)))
return (ETIMEDOUT);
return _umtx_op_err(__DEVOLATILE(void *, mtx),
- shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 0,
+ shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 0,
__DECONST(void*, timeout));
}
int
_thr_umtx_wake(volatile void *mtx, int nr_wakeup, int shared)
{
- return _umtx_op_err(__DEVOLATILE(void *, mtx), shared ? UMTX_OP_WAKE : UMTX_OP_WAKE_PRIVATE,
- nr_wakeup, 0, 0);
+ return _umtx_op_err(__DEVOLATILE(void *, mtx),
+ shared ? UMTX_OP_WAKE : UMTX_OP_WAKE_PRIVATE,
+ nr_wakeup, 0, 0);
}
void
Modified: user/davidxu/libthr/sys/kern/kern_umtx.c
==============================================================================
--- user/davidxu/libthr/sys/kern/kern_umtx.c Thu Nov 4 08:51:45 2010 (r214774)
+++ user/davidxu/libthr/sys/kern/kern_umtx.c Thu Nov 4 08:58:16 2010 (r214775)
@@ -2369,9 +2369,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 timespec *timeout, int mode, int wflags)
{
- struct timespec ts, ts2, ts3;
+ struct timespec cts, ets, tts;
struct timeval tv;
uint32_t flags;
int error;
@@ -2386,21 +2386,30 @@ 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);
+ const clockid_t clockid = CLOCK_REALTIME;
+ if ((wflags & UMUTEX_ABSTIME) == 0) {
+ kern_clock_gettime(td, clockid, &ets);
+ timespecadd(&ets, timeout);
+ tts = *timeout;
+ } else { /* absolute time */
+ ets = *timeout;
+ tts = *timeout;
+ kern_clock_gettime(td, clockid, &cts);
+ timespecsub(&tts, &cts);
+ }
+ TIMESPEC_TO_TIMEVAL(&tv, &tts);
for (;;) {
error = _do_lock_umutex(td, m, flags, tvtohz(&tv), mode);
if (error != ETIMEDOUT)
break;
- getnanouptime(&ts2);
- if (timespeccmp(&ts2, &ts, >=)) {
+ kern_clock_gettime(td, clockid, &cts);
+ if (timespeccmp(&cts, &ets, >=)) {
error = ETIMEDOUT;
break;
}
- ts3 = ts;
- timespecsub(&ts3, &ts2);
- TIMESPEC_TO_TIMEVAL(&tv, &ts3);
+ tts = ets;
+ timespecsub(&tts, &cts);
+ TIMESPEC_TO_TIMEVAL(&tv, &tts);
}
/* Timed-locking is not restarted. */
if (error == ERESTART)
@@ -3513,13 +3522,13 @@ __umtx_op_lock_umutex(struct thread *td,
}
ts = &timeout;
}
- return do_lock_umutex(td, uap->obj, ts, 0);
+ return do_lock_umutex(td, uap->obj, ts, 0, uap->val);
}
static int
__umtx_op_trylock_umutex(struct thread *td, struct _umtx_op_args *uap)
{
- return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY);
+ return do_lock_umutex(td, uap->obj, NULL, _UMUTEX_TRY, 0);
}
static int
@@ -3542,7 +3551,7 @@ __umtx_op_wait_umutex(struct thread *td,
}
ts = &timeout;
}
- return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
+ return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT, uap->val);
}
static int
Modified: user/davidxu/libthr/sys/sys/umtx.h
==============================================================================
--- user/davidxu/libthr/sys/sys/umtx.h Thu Nov 4 08:51:45 2010 (r214774)
+++ user/davidxu/libthr/sys/sys/umtx.h Thu Nov 4 08:58:16 2010 (r214775)
@@ -83,6 +83,9 @@
#define UMTX_OP_SEM_WAKE 20
#define UMTX_OP_MAX 21
+/* flags for UMUTEX_LOCK */
+#define UMUTEX_ABSTIME 0x01
+
/* flags for UMTX_OP_CV_WAIT */
#define CVWAIT_CHECK_UNPARKING 0x01
#define CVWAIT_ABSTIME 0x02
More information about the svn-src-user
mailing list