summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_umtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r--sys/kern/kern_umtx.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 2d2969c..3bc3a78 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -178,7 +178,7 @@ umtxq_unbusy(struct umtx_key *key)
int chain = umtxq_hash(key);
mtx_assert(umtxq_mtx(chain), MA_OWNED);
- KASSERT(umtxq_chains[chain].uc_flags & UCF_BUSY, "not busy");
+ KASSERT(umtxq_chains[chain].uc_flags & UCF_BUSY, ("not busy"));
umtxq_chains[chain].uc_flags &= ~UCF_BUSY;
if (umtxq_chains[chain].uc_flags & UCF_WANT) {
umtxq_chains[chain].uc_flags &= ~UCF_WANT;
@@ -545,13 +545,15 @@ do_lock(struct thread *td, struct umtx *umtx, long id,
}
timo = tvtohz(&tv);
error = _do_lock(td, umtx, id, timo);
- if (error != EWOULDBLOCK) {
- if (error == ERESTART)
- error = EINTR;
+ if (error != EWOULDBLOCK)
break;
- }
}
}
+ /*
+ * This lets userland back off critical region if needed.
+ */
+ if (error == ERESTART)
+ error = EINTR;
return (error);
}
@@ -704,7 +706,9 @@ do_wake(struct thread *td, void *uaddr, int n_wake)
if ((ret = umtx_key_get(td, uaddr, &key)) != 0)
return (ret);
+ umtxq_lock(&key);
ret = umtxq_signal(&key, n_wake);
+ umtxq_unlock(&key);
umtx_key_release(&key);
td->td_retval[0] = ret;
return (0);
OpenPOWER on IntegriCloud