diff options
author | davide <davide@FreeBSD.org> | 2013-03-04 12:20:48 +0000 |
---|---|---|
committer | davide <davide@FreeBSD.org> | 2013-03-04 12:20:48 +0000 |
commit | 7395c58e524e99e35c2ad03ad3dc04b62086b8d9 (patch) | |
tree | 34d2ab5cda6dd8fd98e45b2fe88ab2a372fdec7b | |
parent | 9392b519d74a3f187612fe8b74b119d39eb0a91f (diff) | |
download | FreeBSD-src-7395c58e524e99e35c2ad03ad3dc04b62086b8d9.zip FreeBSD-src-7395c58e524e99e35c2ad03ad3dc04b62086b8d9.tar.gz |
MFcalloutng:
Extend condvar(9) KPI introducing sbt variant of cv_timedwait. This
rely on the previously committed sleepq_set_timeout_sbt().
Sponsored by: Google Summer of Code 2012, iXsystems inc.
Tested by: flo, marius, ian, markj, Fabian Keil
-rw-r--r-- | sys/kern/kern_condvar.c | 25 | ||||
-rw-r--r-- | sys/sys/condvar.h | 16 |
2 files changed, 26 insertions, 15 deletions
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c index 82a997c..483ea2e 100644 --- a/sys/kern/kern_condvar.c +++ b/sys/kern/kern_condvar.c @@ -270,12 +270,13 @@ _cv_wait_sig(struct cv *cvp, struct lock_object *lock) } /* - * Wait on a condition variable for at most timo/hz seconds. Returns 0 if the - * process was resumed by cv_signal or cv_broadcast, EWOULDBLOCK if the timeout - * expires. + * Wait on a condition variable for (at most) the value specified in sbt + * argument. Returns 0 if the process was resumed by cv_signal or cv_broadcast, + * EWOULDBLOCK if the timeout expires. */ int -_cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo) +_cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, sbintime_t sbt, + sbintime_t pr, int flags) { WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; @@ -311,7 +312,7 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo) DROP_GIANT(); sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); - sleepq_set_timeout(cvp, timo); + sleepq_set_timeout_sbt(cvp, sbt, pr, flags); if (lock != &Giant.lock_object) { if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); @@ -336,13 +337,15 @@ _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo) } /* - * Wait on a condition variable for at most timo/hz seconds, allowing - * interruption by signals. Returns 0 if the thread was resumed by cv_signal - * or cv_broadcast, EWOULDBLOCK if the timeout expires, and EINTR or ERESTART if - * a signal was caught. + * Wait on a condition variable for (at most) the value specified in sbt + * argument, allowing interruption by signals. + * Returns 0 if the thread was resumed by cv_signal or cv_broadcast, + * EWOULDBLOCK if the timeout expires, and EINTR or ERESTART if a signal + * was caught. */ int -_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo) +_cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, + sbintime_t sbt, sbintime_t pr, int flags) { WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; @@ -379,7 +382,7 @@ _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo) sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | SLEEPQ_INTERRUPTIBLE, 0); - sleepq_set_timeout(cvp, timo); + sleepq_set_timeout_sbt(cvp, sbt, pr, flags); if (lock != &Giant.lock_object) { if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); diff --git a/sys/sys/condvar.h b/sys/sys/condvar.h index ac97b9c..f940a75 100644 --- a/sys/sys/condvar.h +++ b/sys/sys/condvar.h @@ -55,8 +55,10 @@ void cv_destroy(struct cv *cvp); void _cv_wait(struct cv *cvp, struct lock_object *lock); void _cv_wait_unlock(struct cv *cvp, struct lock_object *lock); int _cv_wait_sig(struct cv *cvp, struct lock_object *lock); -int _cv_timedwait(struct cv *cvp, struct lock_object *lock, int timo); -int _cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, int timo); +int _cv_timedwait_sbt(struct cv *cvp, struct lock_object *lock, + sbintime_t sbt, sbintime_t pr, int flags); +int _cv_timedwait_sig_sbt(struct cv *cvp, struct lock_object *lock, + sbintime_t sbt, sbintime_t pr, int flags); void cv_signal(struct cv *cvp); void cv_broadcastpri(struct cv *cvp, int pri); @@ -68,9 +70,15 @@ void cv_broadcastpri(struct cv *cvp, int pri); #define cv_wait_sig(cvp, lock) \ _cv_wait_sig((cvp), &(lock)->lock_object) #define cv_timedwait(cvp, lock, timo) \ - _cv_timedwait((cvp), &(lock)->lock_object, (timo)) + _cv_timedwait_sbt((cvp), &(lock)->lock_object, \ + tick_sbt * (timo), 0, C_HARDCLOCK) +#define cv_timedwait_sbt(cvp, lock, sbt, pr, flags) \ + _cv_timedwait_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags)) #define cv_timedwait_sig(cvp, lock, timo) \ - _cv_timedwait_sig((cvp), &(lock)->lock_object, (timo)) + _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, \ + tick_sbt * (timo), 0, C_HARDCLOCK) +#define cv_timedwait_sig_sbt(cvp, lock, sbt, pr, flags) \ + _cv_timedwait_sig_sbt((cvp), &(lock)->lock_object, (sbt), (pr), (flags)) #define cv_broadcast(cvp) cv_broadcastpri(cvp, 0) |