aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/cloudabi64
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2018-01-04 21:57:37 +0000
committerEd Schouten <ed@FreeBSD.org>2018-01-04 21:57:37 +0000
commit8e04fe5af3800d1710ff6d5e1d7c210839bbf5e2 (patch)
tree26684c09b8d9b0296b685ef7189171fe5a1b95c4 /sys/compat/cloudabi64
parentfd3bb7aa4609f12853c7ac0fb010babf76e50b5d (diff)
downloadsrc-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.c27
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,