From d31f470d15c45c3e9e32a9d3195623c07a34fe8b Mon Sep 17 00:00:00 2001 From: David Xu Date: Thu, 29 Mar 2012 02:46:43 +0000 Subject: [PATCH] Reduce code size by creating common timed sleeping function. --- sys/kern/kern_umtx.c | 153 +++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 93 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 28eaf8157b2f..b550f4866e47 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -1030,6 +1030,42 @@ tstohz(const struct timespec *tsp) return tvtohz(&tv); } +static int +umtxq_nanosleep(struct thread *td, int clockid, int absolute, + struct timespec *timeout, const char *mesg) +{ + struct umtx_q *uq; + struct timespec ets, cts, tts; + int error; + + uq = td->td_umtxq; + umtxq_unlock(&uq->uq_key); + if (!absolute) { + 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); + } + umtxq_lock(&uq->uq_key); + for (;;) { + error = umtxq_sleep(uq, mesg, tstohz(&tts)); + if (error != ETIMEDOUT) + break; + kern_clock_gettime(td, clockid, &cts); + if (timespeccmp(&cts, &ets, >=)) { + error = ETIMEDOUT; + break; + } + tts = ets; + timespecsub(&tts, &cts); + } + return (error); +} + /* * Fetch and compare value, sleep on the address if value is not changed. */ @@ -1038,7 +1074,6 @@ do_wait(struct thread *td, void *addr, u_long id, struct _umtx_time *timeout, int compat32, int is_private) { struct umtx_q *uq; - struct timespec ets, cts, tts; u_long tmp; int error = 0; @@ -1054,45 +1089,21 @@ do_wait(struct thread *td, void *addr, u_long id, tmp = fuword(addr); else tmp = (unsigned int)fuword32(addr); - if (tmp != id) { - umtxq_lock(&uq->uq_key); - umtxq_remove(uq); - umtxq_unlock(&uq->uq_key); - } else if (timeout == NULL) { - umtxq_lock(&uq->uq_key); - error = umtxq_sleep(uq, "uwait", 0); - umtxq_remove(uq); - umtxq_unlock(&uq->uq_key); - } else { - 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 (;;) { - if (timespeccmp(&cts, &ets, >=)) { - error = ETIMEDOUT; - break; - } - tts = ets; - timespecsub(&tts, &cts); - error = umtxq_sleep(uq, "uwait", tstohz(&tts)); - if (!(uq->uq_flags & UQF_UMTXQ)) { - error = 0; - break; - } - if (error != ETIMEDOUT) - break; - umtxq_unlock(&uq->uq_key); - kern_clock_gettime(td, timeout->_clockid, &cts); - umtxq_lock(&uq->uq_key); - } - umtxq_remove(uq); - umtxq_unlock(&uq->uq_key); + umtxq_lock(&uq->uq_key); + if (tmp == id) { + if (timeout == NULL) + error = umtxq_sleep(uq, "uwait", 0); + else + error = umtxq_nanosleep(td, timeout->_clockid, + ((timeout->_flags & UMTX_ABSTIME) != 0), + &timeout->_timeout, "uwait"); } + + if ((uq->uq_flags & UQF_UMTXQ) == 0) + error = 0; + else + umtxq_remove(uq); + umtxq_unlock(&uq->uq_key); umtx_key_release(&uq->uq_key); if (error == ERESTART) error = EINTR; @@ -2340,7 +2351,6 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, struct timespec *timeout, u_long wflags) { struct umtx_q *uq; - struct timespec cts, ets, tts; uint32_t flags; uint32_t clockid; int error; @@ -2382,32 +2392,12 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, umtxq_lock(&uq->uq_key); if (error == 0) { - if (timeout == NULL) { + if (timeout == NULL) error = umtxq_sleep(uq, "ucond", 0); - } else { - if ((wflags & CVWAIT_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); - } - for (;;) { - error = umtxq_sleep(uq, "ucond", tstohz(&tts)); - if (error != ETIMEDOUT) - break; - kern_clock_gettime(td, clockid, &cts); - if (timespeccmp(&cts, &ets, >=)) { - error = ETIMEDOUT; - break; - } - tts = ets; - timespecsub(&tts, &cts); - } - } + else + error = umtxq_nanosleep(td, clockid, + ((wflags & CVWAIT_ABSTIME) != 0), + timeout, "ucond"); } if ((uq->uq_flags & UQF_UMTXQ) == 0) @@ -2856,7 +2846,6 @@ static int do_sem_wait(struct thread *td, struct _usem *sem, struct _umtx_time *timeout) { struct umtx_q *uq; - struct timespec cts, ets, tts; uint32_t flags, count; int error; @@ -2881,37 +2870,15 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct _umtx_time *timeout) umtx_key_release(&uq->uq_key); return (0); } - umtxq_lock(&uq->uq_key); umtxq_unbusy(&uq->uq_key); - if (timeout == NULL) { + if (timeout == NULL) error = umtxq_sleep(uq, "usem", 0); - } else { - 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 (;;) { - if (timespeccmp(&cts, &ets, >=)) { - error = ETIMEDOUT; - break; - } - tts = ets; - timespecsub(&tts, &cts); - 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); - } - } + else + error = umtxq_nanosleep(td, timeout->_clockid, + ((timeout->_flags & UMTX_ABSTIME) != 0), + &timeout->_timeout, "usem"); if ((uq->uq_flags & UQF_UMTXQ) == 0) error = 0;