Date: Thu, 29 Mar 2012 02:46:43 +0000 (UTC) From: David Xu <davidxu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r233642 - head/sys/kern Message-ID: <201203290246.q2T2khhF072050@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davidxu Date: Thu Mar 29 02:46:43 2012 New Revision: 233642 URL: http://svn.freebsd.org/changeset/base/233642 Log: Reduce code size by creating common timed sleeping function. Modified: head/sys/kern/kern_umtx.c Modified: head/sys/kern/kern_umtx.c ============================================================================== --- head/sys/kern/kern_umtx.c Thu Mar 29 02:45:50 2012 (r233641) +++ head/sys/kern/kern_umtx.c Thu Mar 29 02:46:43 2012 (r233642) @@ -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 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 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 uco 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 uco 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 _u 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203290246.q2T2khhF072050>