From 7b8d8212689d38853a46b931c1e1cbb23264b3a8 Mon Sep 17 00:00:00 2001 From: David Xu Date: Thu, 18 May 2006 08:43:46 +0000 Subject: [PATCH] Move flag TDF_UMTXQ into structure umtxq, this eliminates the requirement of scheduler lock in some umtx code. --- sys/kern/kern_umtx.c | 27 ++++++++++++--------------- sys/sys/proc.h | 2 +- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 12111183bdb1..cb248a855f5c 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -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; } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 19997af73a6e..de40963eddf7 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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 -- */