Move flag TDF_UMTXQ into structure umtxq, this eliminates the requirement
of scheduler lock in some umtx code.
This commit is contained in:
parent
c3c820369e
commit
7b8d821268
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158718
@ -72,8 +72,9 @@ struct umtx_key {
|
||||
struct umtx_q {
|
||||
LIST_ENTRY(umtx_q) uq_next; /* Linked list for the hash. */
|
||||
struct umtx_key uq_key; /* Umtx key. */
|
||||
int uq_flags; /* Umtx flags. */
|
||||
#define UQF_UMTXQ 0x0001
|
||||
struct thread *uq_thread; /* The thread waits on. */
|
||||
LIST_ENTRY(umtx_q) uq_rqnext; /* Linked list for requeuing. */
|
||||
vm_offset_t uq_addr; /* Umtx's virtual address. */
|
||||
};
|
||||
|
||||
@ -116,7 +117,7 @@ SYSINIT(umtx, SI_SUB_EVENTHANDLER+1, SI_ORDER_MIDDLE, umtxq_init_chains, NULL);
|
||||
struct umtx_q *
|
||||
umtxq_alloc(void)
|
||||
{
|
||||
return (malloc(sizeof(struct umtx_q), M_UMTX, M_WAITOK));
|
||||
return (malloc(sizeof(struct umtx_q), M_UMTX, M_WAITOK|M_ZERO));
|
||||
}
|
||||
|
||||
void
|
||||
@ -213,9 +214,7 @@ umtxq_insert(struct umtx_q *uq)
|
||||
mtx_assert(umtxq_mtx(chain), MA_OWNED);
|
||||
head = &umtxq_chains[chain].uc_queue;
|
||||
LIST_INSERT_HEAD(head, uq, uq_next);
|
||||
mtx_lock_spin(&sched_lock);
|
||||
uq->uq_thread->td_flags |= TDF_UMTXQ;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
uq->uq_flags |= UQF_UMTXQ;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -225,12 +224,10 @@ static inline void
|
||||
umtxq_remove(struct umtx_q *uq)
|
||||
{
|
||||
mtx_assert(umtxq_mtx(umtxq_hash(&uq->uq_key)), MA_OWNED);
|
||||
if (uq->uq_thread->td_flags & TDF_UMTXQ) {
|
||||
if (uq->uq_flags & UQF_UMTXQ) {
|
||||
LIST_REMOVE(uq, uq_next);
|
||||
/* turning off TDF_UMTXQ should be the last thing. */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
uq->uq_thread->td_flags &= ~TDF_UMTXQ;
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
/* turning off UQF_UMTXQ should be the last thing. */
|
||||
uq->uq_flags &= ~UQF_UMTXQ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,7 +420,7 @@ _do_lock(struct thread *td, struct umtx *umtx, long id, int timo)
|
||||
* unlocking the umtx.
|
||||
*/
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (old == owner && (td->td_flags & TDF_UMTXQ)) {
|
||||
if (old == owner && (uq->uq_flags & UQF_UMTXQ)) {
|
||||
error = umtxq_sleep(td, &uq->uq_key, PCATCH,
|
||||
"umtx", timo);
|
||||
}
|
||||
@ -544,10 +541,10 @@ do_wait(struct thread *td, struct umtx *umtx, long id, struct timespec *timeout)
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
} else if (timeout == NULL) {
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (td->td_flags & TDF_UMTXQ)
|
||||
if (uq->uq_flags & UQF_UMTXQ)
|
||||
error = umtxq_sleep(td, &uq->uq_key,
|
||||
PCATCH, "ucond", 0);
|
||||
if (!(td->td_flags & TDF_UMTXQ))
|
||||
if (!(uq->uq_flags & UQF_UMTXQ))
|
||||
error = 0;
|
||||
else
|
||||
umtxq_remove(uq);
|
||||
@ -558,11 +555,11 @@ do_wait(struct thread *td, struct umtx *umtx, long id, struct timespec *timeout)
|
||||
TIMESPEC_TO_TIMEVAL(&tv, timeout);
|
||||
for (;;) {
|
||||
umtxq_lock(&uq->uq_key);
|
||||
if (td->td_flags & TDF_UMTXQ) {
|
||||
if (uq->uq_flags & UQF_UMTXQ) {
|
||||
error = umtxq_sleep(td, &uq->uq_key, PCATCH,
|
||||
"ucond", tvtohz(&tv));
|
||||
}
|
||||
if (!(td->td_flags & TDF_UMTXQ)) {
|
||||
if (!(uq->uq_flags & UQF_UMTXQ)) {
|
||||
umtxq_unlock(&uq->uq_key);
|
||||
goto out;
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ struct thread {
|
||||
#define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */
|
||||
#define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */
|
||||
#define TDF_XSIG 0x00040000 /* Thread is exchanging signal under trace */
|
||||
#define TDF_UMTXQ 0x00080000 /* Thread is sleeping on a umtx. */
|
||||
#define TDF_UNUSED19 0x00080000 /* Thread is sleeping on a umtx. */
|
||||
#define TDF_THRWAKEUP 0x00100000 /* Libthr thread must not suspend itself. */
|
||||
#define TDF_DBSUSPEND 0x00200000 /* Thread is suspended by debugger */
|
||||
#define TDF_UNUSED22 0x00400000 /* --available -- */
|
||||
|
Loading…
Reference in New Issue
Block a user