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 {
|
struct umtx_q {
|
||||||
LIST_ENTRY(umtx_q) uq_next; /* Linked list for the hash. */
|
LIST_ENTRY(umtx_q) uq_next; /* Linked list for the hash. */
|
||||||
struct umtx_key uq_key; /* Umtx key. */
|
struct umtx_key uq_key; /* Umtx key. */
|
||||||
|
int uq_flags; /* Umtx flags. */
|
||||||
|
#define UQF_UMTXQ 0x0001
|
||||||
struct thread *uq_thread; /* The thread waits on. */
|
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. */
|
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 *
|
struct umtx_q *
|
||||||
umtxq_alloc(void)
|
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
|
void
|
||||||
@ -213,9 +214,7 @@ umtxq_insert(struct umtx_q *uq)
|
|||||||
mtx_assert(umtxq_mtx(chain), MA_OWNED);
|
mtx_assert(umtxq_mtx(chain), MA_OWNED);
|
||||||
head = &umtxq_chains[chain].uc_queue;
|
head = &umtxq_chains[chain].uc_queue;
|
||||||
LIST_INSERT_HEAD(head, uq, uq_next);
|
LIST_INSERT_HEAD(head, uq, uq_next);
|
||||||
mtx_lock_spin(&sched_lock);
|
uq->uq_flags |= UQF_UMTXQ;
|
||||||
uq->uq_thread->td_flags |= TDF_UMTXQ;
|
|
||||||
mtx_unlock_spin(&sched_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -225,12 +224,10 @@ static inline void
|
|||||||
umtxq_remove(struct umtx_q *uq)
|
umtxq_remove(struct umtx_q *uq)
|
||||||
{
|
{
|
||||||
mtx_assert(umtxq_mtx(umtxq_hash(&uq->uq_key)), MA_OWNED);
|
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);
|
LIST_REMOVE(uq, uq_next);
|
||||||
/* turning off TDF_UMTXQ should be the last thing. */
|
/* turning off UQF_UMTXQ should be the last thing. */
|
||||||
mtx_lock_spin(&sched_lock);
|
uq->uq_flags &= ~UQF_UMTXQ;
|
||||||
uq->uq_thread->td_flags &= ~TDF_UMTXQ;
|
|
||||||
mtx_unlock_spin(&sched_lock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +420,7 @@ _do_lock(struct thread *td, struct umtx *umtx, long id, int timo)
|
|||||||
* unlocking the umtx.
|
* unlocking the umtx.
|
||||||
*/
|
*/
|
||||||
umtxq_lock(&uq->uq_key);
|
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,
|
error = umtxq_sleep(td, &uq->uq_key, PCATCH,
|
||||||
"umtx", timo);
|
"umtx", timo);
|
||||||
}
|
}
|
||||||
@ -544,10 +541,10 @@ do_wait(struct thread *td, struct umtx *umtx, long id, struct timespec *timeout)
|
|||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
} else if (timeout == NULL) {
|
} else if (timeout == NULL) {
|
||||||
umtxq_lock(&uq->uq_key);
|
umtxq_lock(&uq->uq_key);
|
||||||
if (td->td_flags & TDF_UMTXQ)
|
if (uq->uq_flags & UQF_UMTXQ)
|
||||||
error = umtxq_sleep(td, &uq->uq_key,
|
error = umtxq_sleep(td, &uq->uq_key,
|
||||||
PCATCH, "ucond", 0);
|
PCATCH, "ucond", 0);
|
||||||
if (!(td->td_flags & TDF_UMTXQ))
|
if (!(uq->uq_flags & UQF_UMTXQ))
|
||||||
error = 0;
|
error = 0;
|
||||||
else
|
else
|
||||||
umtxq_remove(uq);
|
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);
|
TIMESPEC_TO_TIMEVAL(&tv, timeout);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
umtxq_lock(&uq->uq_key);
|
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,
|
error = umtxq_sleep(td, &uq->uq_key, PCATCH,
|
||||||
"ucond", tvtohz(&tv));
|
"ucond", tvtohz(&tv));
|
||||||
}
|
}
|
||||||
if (!(td->td_flags & TDF_UMTXQ)) {
|
if (!(uq->uq_flags & UQF_UMTXQ)) {
|
||||||
umtxq_unlock(&uq->uq_key);
|
umtxq_unlock(&uq->uq_key);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ struct thread {
|
|||||||
#define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */
|
#define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */
|
||||||
#define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */
|
#define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */
|
||||||
#define TDF_XSIG 0x00040000 /* Thread is exchanging signal under trace */
|
#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_THRWAKEUP 0x00100000 /* Libthr thread must not suspend itself. */
|
||||||
#define TDF_DBSUSPEND 0x00200000 /* Thread is suspended by debugger */
|
#define TDF_DBSUSPEND 0x00200000 /* Thread is suspended by debugger */
|
||||||
#define TDF_UNUSED22 0x00400000 /* --available -- */
|
#define TDF_UNUSED22 0x00400000 /* --available -- */
|
||||||
|
Loading…
Reference in New Issue
Block a user