diff options
author | Ed Schouten <ed@FreeBSD.org> | 2018-01-04 21:57:37 +0000 |
---|---|---|
committer | Ed Schouten <ed@FreeBSD.org> | 2018-01-04 21:57:37 +0000 |
commit | 8e04fe5af3800d1710ff6d5e1d7c210839bbf5e2 (patch) | |
tree | 26684c09b8d9b0296b685ef7189171fe5a1b95c4 /sys/compat/cloudabi64 | |
parent | fd3bb7aa4609f12853c7ac0fb010babf76e50b5d (diff) | |
download | src-8e04fe5af3800d1710ff6d5e1d7c210839bbf5e2.tar.gz src-8e04fe5af3800d1710ff6d5e1d7c210839bbf5e2.zip |
Allow timed waits with relative timeouts on locks and condvars.
Even though pthreads doesn't support this, there are various alternative
APIs that use this. For example, uv_cond_timedwait() accepts a relative
timeout. So does Rust's std::sync::Condvar::wait_timeout().
Though I personally think that relative timeouts are bad (due to
imprecision for repeated operations), it does seem that people want
this. Extend the existing futex functions to keep track of whether an
absolute timeout is used in a boolean flag.
MFC after: 1 month
Notes
Notes:
svn path=/head/; revision=327560
Diffstat (limited to 'sys/compat/cloudabi64')
-rw-r--r-- | sys/compat/cloudabi64/cloudabi64_poll.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/sys/compat/cloudabi64/cloudabi64_poll.c b/sys/compat/cloudabi64/cloudabi64_poll.c index 52950928b27c..2d3d87f3ac7f 100644 --- a/sys/compat/cloudabi64/cloudabi64_poll.c +++ b/sys/compat/cloudabi64/cloudabi64_poll.c @@ -243,7 +243,7 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) sub.condvar.condvar_scope, TO_PTR(sub.condvar.lock), sub.condvar.lock_scope, - CLOUDABI_CLOCK_MONOTONIC, UINT64_MAX, 0)); + CLOUDABI_CLOCK_MONOTONIC, UINT64_MAX, 0, true)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } else if (sub.type == CLOUDABI_EVENTTYPE_LOCK_RDLOCK) { @@ -252,7 +252,7 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) cloudabi_futex_lock_rdlock( td, TO_PTR(sub.lock.lock), sub.lock.lock_scope, CLOUDABI_CLOCK_MONOTONIC, - UINT64_MAX, 0)); + UINT64_MAX, 0, true)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } else if (sub.type == CLOUDABI_EVENTTYPE_LOCK_WRLOCK) { @@ -261,7 +261,7 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) cloudabi_futex_lock_wrlock( td, TO_PTR(sub.lock.lock), sub.lock.lock_scope, CLOUDABI_CLOCK_MONOTONIC, - UINT64_MAX, 0)); + UINT64_MAX, 0, true)); td->td_retval[0] = 1; return (copyout(&ev, uap->out, sizeof(ev))); } @@ -278,15 +278,16 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) ev[1].userdata = sub[1].userdata; ev[1].type = sub[1].type; if (sub[0].type == CLOUDABI_EVENTTYPE_CONDVAR && - sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && - sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { + sub[1].type == CLOUDABI_EVENTTYPE_CLOCK) { /* Wait for a condition variable with timeout. */ error = cloudabi_futex_condvar_wait( td, TO_PTR(sub[0].condvar.condvar), sub[0].condvar.condvar_scope, TO_PTR(sub[0].condvar.lock), sub[0].condvar.lock_scope, sub[1].clock.clock_id, - sub[1].clock.timeout, sub[1].clock.precision); + sub[1].clock.timeout, sub[1].clock.precision, + (sub[1].clock.flags & + CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) != 0); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, @@ -297,13 +298,14 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) td->td_retval[0] = 1; return (copyout(&ev[0], uap->out, sizeof(ev[0]))); } else if (sub[0].type == CLOUDABI_EVENTTYPE_LOCK_RDLOCK && - sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && - sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { + sub[1].type == CLOUDABI_EVENTTYPE_CLOCK) { /* Acquire a read lock with a timeout. */ error = cloudabi_futex_lock_rdlock( td, TO_PTR(sub[0].lock.lock), sub[0].lock.lock_scope, sub[1].clock.clock_id, - sub[1].clock.timeout, sub[1].clock.precision); + sub[1].clock.timeout, sub[1].clock.precision, + (sub[1].clock.flags & + CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) != 0); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, @@ -314,13 +316,14 @@ cloudabi64_sys_poll(struct thread *td, struct cloudabi64_sys_poll_args *uap) td->td_retval[0] = 1; return (copyout(&ev[0], uap->out, sizeof(ev[0]))); } else if (sub[0].type == CLOUDABI_EVENTTYPE_LOCK_WRLOCK && - sub[1].type == CLOUDABI_EVENTTYPE_CLOCK && - sub[1].clock.flags == CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) { + sub[1].type == CLOUDABI_EVENTTYPE_CLOCK) { /* Acquire a write lock with a timeout. */ error = cloudabi_futex_lock_wrlock( td, TO_PTR(sub[0].lock.lock), sub[0].lock.lock_scope, sub[1].clock.clock_id, - sub[1].clock.timeout, sub[1].clock.precision); + sub[1].clock.timeout, sub[1].clock.precision, + (sub[1].clock.flags & + CLOUDABI_SUBSCRIPTION_CLOCK_ABSTIME) != 0); if (error == ETIMEDOUT) { td->td_retval[0] = 1; return (copyout(&ev[1], uap->out, |