If a thread is removed from umtxq while sleeping, reset error code
to zero, this gives userland a better indication that a thread needn't to be cancelled.
This commit is contained in:
parent
253953cd5b
commit
df7442533c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211794
@ -1059,8 +1059,10 @@ do_wait(struct thread *td, void *addr, u_long id,
|
|||||||
umtxq_lock(&uq->uq_key);
|
umtxq_lock(&uq->uq_key);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
error = umtxq_sleep(uq, "uwait", tvtohz(&tv));
|
error = umtxq_sleep(uq, "uwait", tvtohz(&tv));
|
||||||
if (!(uq->uq_flags & UQF_UMTXQ))
|
if (!(uq->uq_flags & UQF_UMTXQ)) {
|
||||||
|
error = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (error != ETIMEDOUT)
|
if (error != ETIMEDOUT)
|
||||||
break;
|
break;
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
@ -2404,25 +2406,14 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != 0) {
|
if ((uq->uq_flags & UQF_UMTXQ) == 0)
|
||||||
if ((uq->uq_flags & UQF_UMTXQ) == 0) {
|
error = 0;
|
||||||
/*
|
else {
|
||||||
* If we concurrently got do_cv_signal()d
|
umtxq_remove(uq);
|
||||||
* and we got an error or UNIX signals or a timeout,
|
|
||||||
* then, perform another umtxq_signal to avoid
|
|
||||||
* consuming the wakeup. This may cause supurious
|
|
||||||
* wakeup for another thread which was just queued,
|
|
||||||
* but SUSV3 explicitly allows supurious wakeup to
|
|
||||||
* occur, and indeed a kernel based implementation
|
|
||||||
* can not avoid it.
|
|
||||||
*/
|
|
||||||
if (!umtxq_signal(&uq->uq_key, 1))
|
|
||||||
error = 0;
|
|
||||||
}
|
|
||||||
if (error == ERESTART)
|
if (error == ERESTART)
|
||||||
error = EINTR;
|
error = EINTR;
|
||||||
}
|
}
|
||||||
umtxq_remove(uq);
|
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
umtx_key_release(&uq->uq_key);
|
umtx_key_release(&uq->uq_key);
|
||||||
return (error);
|
return (error);
|
||||||
@ -2891,15 +2882,13 @@ do_sem_wait(struct thread *td, struct _usem *sem, struct timespec *timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != 0) {
|
if ((uq->uq_flags & UQF_UMTXQ) == 0)
|
||||||
if ((uq->uq_flags & UQF_UMTXQ) == 0) {
|
error = 0;
|
||||||
if (!umtxq_signal(&uq->uq_key, 1))
|
else {
|
||||||
error = 0;
|
umtxq_remove(uq);
|
||||||
}
|
|
||||||
if (error == ERESTART)
|
if (error == ERESTART)
|
||||||
error = EINTR;
|
error = EINTR;
|
||||||
}
|
}
|
||||||
umtxq_remove(uq);
|
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
umtx_key_release(&uq->uq_key);
|
umtx_key_release(&uq->uq_key);
|
||||||
return (error);
|
return (error);
|
||||||
|
Loading…
Reference in New Issue
Block a user