Move flag TDF_UMTXQ into structure umtxq, this eliminates the requirement

of scheduler lock in some umtx code.
This commit is contained in:
David Xu 2006-05-18 08:43:46 +00:00
parent c3c820369e
commit 7b8d821268
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=158718
2 changed files with 13 additions and 16 deletions

View File

@ -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;
}

View File

@ -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 -- */