From owner-p4-projects@FreeBSD.ORG Sat Nov 20 04:27:48 2004 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id BA23E16A4D0; Sat, 20 Nov 2004 04:27:47 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7F35616A4CE for ; Sat, 20 Nov 2004 04:27:47 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4EC7043D4C for ; Sat, 20 Nov 2004 04:27:47 +0000 (GMT) (envelope-from davidxu@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.11/8.12.11) with ESMTP id iAK4RlDF005921 for ; Sat, 20 Nov 2004 04:27:47 GMT (envelope-from davidxu@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.11/8.12.11/Submit) id iAK4RlwS005918 for perforce@freebsd.org; Sat, 20 Nov 2004 04:27:47 GMT (envelope-from davidxu@freebsd.org) Date: Sat, 20 Nov 2004 04:27:47 GMT Message-Id: <200411200427.iAK4RlwS005918@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to davidxu@freebsd.org using -f From: David Xu To: Perforce Change Reviews Subject: PERFORCE change 65511 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Nov 2004 04:27:48 -0000 http://perforce.freebsd.org/chv.cgi?CH=65511 Change 65511 by davidxu@davidxu_alona on 2004/11/20 04:27:09 1. Fix thr_mutex_init to handle current thread as an owner specially. 2. Fix signal backout code bug. 3. Use thr kernel interfaces. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_mutex.c#2 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_mutex.c#2 (text+ko) ==== @@ -74,7 +74,7 @@ /* * Prototypes */ -static struct kse_mailbox *mutex_handoff(struct pthread *, +static long mutex_handoff(struct pthread *, struct pthread_mutex *); static inline int mutex_self_trylock(struct pthread *, pthread_mutex_t); static inline int mutex_self_lock(struct pthread *, pthread_mutex_t); @@ -85,8 +85,8 @@ static inline pthread_t mutex_queue_deq(pthread_mutex_t); static inline void mutex_queue_remove(pthread_mutex_t, pthread_t); static inline void mutex_queue_enq(pthread_mutex_t, pthread_t); +static void mutex_lock_backout(void *arg); - static struct pthread_mutex_attr static_mutex_attr = PTHREAD_MUTEXATTR_STATIC_INITIALIZER; static pthread_mutexattr_t static_mattr = &static_mutex_attr; @@ -151,8 +151,7 @@ if ((pmutex = (pthread_mutex_t) malloc(sizeof(struct pthread_mutex))) == NULL) ret = ENOMEM; - else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) { + else if (_lock_init(&pmutex->m_lock) != 0) { free(pmutex); *mutex = NULL; ret = ENOMEM; @@ -207,13 +206,16 @@ } void -_thr_mutex_reinit(pthread_mutex_t *mutex) +_thr_mutex_reinit(struct pthread *curthread, pthread_mutex_t *mutex) { - _lock_reinit(&(*mutex)->m_lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup); + _lock_reinit(&(*mutex)->m_lock); TAILQ_INIT(&(*mutex)->m_queue); - (*mutex)->m_owner = NULL; - (*mutex)->m_count = 0; + if (curthread == NULL || + (*mutex)->m_owner != curthread) { + MUTEX_INIT_LINK(*mutex); + (*mutex)->m_owner = NULL; + (*mutex)->m_count = 0; + } (*mutex)->m_refcount = 0; (*mutex)->m_prio = 0; (*mutex)->m_saved_prio = 0; @@ -348,7 +350,7 @@ /* Lock the mutex for the running thread: */ (*mutex)->m_owner = curthread; - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); /* Track number of priority mutexes owned: */ curthread->priority_mutex_count++; @@ -360,7 +362,7 @@ (*mutex)->m_saved_prio = curthread->inherited_priority; curthread->inherited_priority = (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Add to the list of owned mutexes: */ MUTEX_ASSERT_NOT_OWNED(*mutex); @@ -384,7 +386,7 @@ /* Lock the mutex for the running thread: */ (*mutex)->m_owner = curthread; - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); /* Track number of priority mutexes owned: */ curthread->priority_mutex_count++; @@ -398,7 +400,7 @@ curthread->inherited_priority; curthread->inherited_priority = (*mutex)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Add to the list of owned mutexes: */ MUTEX_ASSERT_NOT_OWNED(*mutex); TAILQ_INSERT_TAIL(&curthread->mutexq, @@ -471,7 +473,7 @@ int ret = 0; THR_ASSERT((m != NULL) && (*m != NULL), - "Uninitialized mutex in pthread_mutex_trylock_basic"); + "Uninitialized mutex in mutex_lock_common"); if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) @@ -539,27 +541,32 @@ */ mutex_queue_enq(*m, curthread); curthread->data.mutex = *m; + curthread->sigbackout = mutex_lock_backout; /* * This thread is active and is in a critical * region (holding the mutex lock); we should * be able to safely set the state. */ - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK_SWITCH(curthread); THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); /* Schedule the next thread: */ - _thr_sched_switch(curthread); + _thr_sched_switch_unlocked(curthread); - curthread->data.mutex = NULL; if (THR_IN_MUTEXQ(curthread)) { THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); mutex_queue_remove(*m, curthread); THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } + /* + * Only clear these after assuring the + * thread is dequeued. + */ + curthread->data.mutex = NULL; + curthread->sigbackout = NULL; } break; @@ -570,7 +577,7 @@ /* Lock the mutex for this thread: */ (*m)->m_owner = curthread; - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); /* Track number of priority mutexes owned: */ curthread->priority_mutex_count++; @@ -584,7 +591,7 @@ (*m)->m_saved_prio = curthread->inherited_priority; curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Add to the list of owned mutexes: */ MUTEX_ASSERT_NOT_OWNED(*m); @@ -613,6 +620,7 @@ */ mutex_queue_enq(*m, curthread); curthread->data.mutex = *m; + curthread->sigbackout = mutex_lock_backout; /* * This thread is active and is in a critical @@ -623,22 +631,26 @@ /* Adjust priorities: */ mutex_priority_adjust(curthread, *m); - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK_SWITCH(curthread); THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); /* Schedule the next thread: */ - _thr_sched_switch(curthread); + _thr_sched_switch_unlocked(curthread); - curthread->data.mutex = NULL; if (THR_IN_MUTEXQ(curthread)) { THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock); mutex_queue_remove(*m, curthread); THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } + /* + * Only clear these after assuring the + * thread is dequeued. + */ + curthread->data.mutex = NULL; + curthread->sigbackout = NULL; } break; @@ -658,7 +670,7 @@ */ (*m)->m_owner = curthread; - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); /* Track number of priority mutexes owned: */ curthread->priority_mutex_count++; @@ -673,7 +685,7 @@ (*m)->m_saved_prio = curthread->inherited_priority; curthread->inherited_priority = (*m)->m_prio; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Add to the list of owned mutexes: */ MUTEX_ASSERT_NOT_OWNED(*m); @@ -702,6 +714,7 @@ */ mutex_queue_enq(*m, curthread); curthread->data.mutex = *m; + curthread->sigbackout = mutex_lock_backout; /* Clear any previous error: */ curthread->error = 0; @@ -712,15 +725,14 @@ * be able to safely set the state. */ - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK_SWITCH(curthread); THR_SET_STATE(curthread, PS_MUTEX_WAIT); - THR_SCHED_UNLOCK(curthread, curthread); /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); /* Schedule the next thread: */ - _thr_sched_switch(curthread); + _thr_sched_switch_unlocked(curthread); curthread->data.mutex = NULL; if (THR_IN_MUTEXQ(curthread)) { @@ -728,6 +740,12 @@ mutex_queue_remove(*m, curthread); THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } + /* + * Only clear these after assuring the + * thread is dequeued. + */ + curthread->data.mutex = NULL; + curthread->sigbackout = NULL; /* * The threads priority may have changed while @@ -781,8 +799,7 @@ struct pthread *curthread; int ret = 0; - if (_thr_initial == NULL) - _libpthread_init(NULL); + _thr_check_init(); curthread = _get_curthread(); if (m == NULL) @@ -806,8 +823,8 @@ struct pthread *curthread; int ret = 0; - if (_thr_initial == NULL) - _libpthread_init(NULL); + _thr_check_init(); + curthread = _get_curthread(); if (m == NULL) @@ -831,8 +848,7 @@ struct pthread *curthread; int ret = 0; - if (_thr_initial == NULL) - _libpthread_init(NULL); + _thr_check_init(); curthread = _get_curthread(); if (m == NULL) @@ -855,8 +871,8 @@ struct pthread *curthread; int ret = 0; - if (_thr_initial == NULL) - _libpthread_init(NULL); + _thr_check_init(); + curthread = _get_curthread(); if (m == NULL) @@ -948,15 +964,14 @@ * deadlock on attempts to get a lock you already own. */ - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK_SWITCH(curthread); THR_SET_STATE(curthread, PS_DEADLOCK); - THR_SCHED_UNLOCK(curthread, curthread); /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &m->m_lock); /* Schedule the next thread: */ - _thr_sched_switch(curthread); + _thr_sched_switch_unlocked(curthread); break; case PTHREAD_MUTEX_RECURSIVE: @@ -976,7 +991,7 @@ mutex_unlock_common(pthread_mutex_t *m, int add_reference) { struct pthread *curthread = _get_curthread(); - struct kse_mailbox *kmbx = NULL; + long tid = -1; int ret = 0; if (m == NULL || *m == NULL) @@ -1016,7 +1031,7 @@ * Hand off the mutex to the next waiting * thread: */ - kmbx = mutex_handoff(curthread, *m); + tid = mutex_handoff(curthread, *m); } break; @@ -1045,7 +1060,7 @@ * not to override changes in the threads base * priority subsequent to locking the mutex). */ - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); curthread->inherited_priority = (*m)->m_saved_prio; curthread->active_priority = @@ -1056,7 +1071,7 @@ * This thread now owns one less priority mutex. */ curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Remove the mutex from the threads queue. */ MUTEX_ASSERT_IS_OWNED(*m); @@ -1068,7 +1083,7 @@ * Hand off the mutex to the next waiting * thread: */ - kmbx = mutex_handoff(curthread, *m); + tid = mutex_handoff(curthread, *m); } break; @@ -1097,7 +1112,7 @@ * not to override changes in the threads base * priority subsequent to locking the mutex). */ - THR_SCHED_LOCK(curthread, curthread); + THR_LOCK(curthread); curthread->inherited_priority = (*m)->m_saved_prio; curthread->active_priority = @@ -1108,7 +1123,7 @@ * This thread now owns one less priority mutex. */ curthread->priority_mutex_count--; - THR_SCHED_UNLOCK(curthread, curthread); + THR_UNLOCK(curthread); /* Remove the mutex from the threads queue. */ MUTEX_ASSERT_IS_OWNED(*m); @@ -1120,7 +1135,7 @@ * Hand off the mutex to the next waiting * thread: */ - kmbx = mutex_handoff(curthread, *m); + tid = mutex_handoff(curthread, *m); } break; @@ -1137,8 +1152,8 @@ /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); - if (kmbx != NULL) - kse_wakeup(kmbx); + if (tid != -1) + thr_wake(tid); } /* Return the completion status: */ @@ -1207,11 +1222,11 @@ * mutex locks held. The thread's pointer to the wanted * mutex is guaranteed to be valid during this time. */ - THR_SCHED_LOCK(curthread, pthread); + THR_THREAD_LOCK(curthread, pthread); if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) == 0) || ((m = pthread->data.mutex) == NULL)) - THR_SCHED_UNLOCK(curthread, pthread); + THR_THREAD_UNLOCK(curthread, pthread); else { /* * This thread is currently waiting on a mutex; unlock @@ -1219,7 +1234,7 @@ * can't hold both at the same time because the locking * order could cause a deadlock. */ - THR_SCHED_UNLOCK(curthread, pthread); + THR_THREAD_UNLOCK(curthread, pthread); THR_LOCK_ACQUIRE(curthread, &m->m_lock); /* @@ -1456,9 +1471,10 @@ if (active_prio != pthread->active_priority) { /* Lock the thread's scheduling queue: */ - THR_SCHED_LOCK(curthread, pthread); + THR_THREAD_LOCK(curthread, pthread); - if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) { + /* if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) */ + if (1) { /* * This thread is not in a run queue. Just set * its active priority. @@ -1470,8 +1486,7 @@ * This thread is in a run queue. Remove it from * the queue before changing its priority: */ - THR_RUNQ_REMOVE(pthread); - + /* THR_RUNQ_REMOVE(pthread);*/ /* * POSIX states that if the priority is being * lowered, the thread must be inserted at the @@ -1482,16 +1497,14 @@ (pthread->priority_mutex_count > 0)) { /* Set the new active priority. */ pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_HEAD(pthread); + /* THR_RUNQ_INSERT_HEAD(pthread); */ } else { /* Set the new active priority. */ pthread->active_priority = active_prio; - - THR_RUNQ_INSERT_TAIL(pthread); + /* THR_RUNQ_INSERT_TAIL(pthread);*/ } } - THR_SCHED_UNLOCK(curthread, pthread); + THR_THREAD_UNLOCK(curthread, pthread); } } @@ -1511,9 +1524,10 @@ * This is called by the current thread when it wants to back out of a * mutex_lock in order to run a signal handler. */ -void -_mutex_lock_backout(struct pthread *curthread) +static void +mutex_lock_backout(void *arg) { + struct pthread *curthread = (struct pthread *)arg; struct pthread_mutex *m; if ((curthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) { @@ -1530,8 +1544,8 @@ /* Lock the mutex structure: */ THR_LOCK_ACQUIRE(curthread, &m->m_lock); + curthread->data.mutex = NULL; - /* * Check to make sure this thread doesn't already own * the mutex. Since mutexes are unlocked with direct @@ -1554,6 +1568,8 @@ THR_LOCK_RELEASE(curthread, &m->m_lock); } } + /* No need to call this again. */ + curthread->sigbackout = NULL; } /* @@ -1565,18 +1581,18 @@ * is necessary to lock the thread's scheduling queue while also * holding the mutex lock. */ -static struct kse_mailbox * +static long mutex_handoff(struct pthread *curthread, struct pthread_mutex *mutex) { - struct kse_mailbox *kmbx = NULL; struct pthread *pthread; + long tid = -1; /* Keep dequeueing until we find a valid thread: */ mutex->m_owner = NULL; pthread = TAILQ_FIRST(&mutex->m_queue); while (pthread != NULL) { /* Take the thread's scheduling lock: */ - THR_SCHED_LOCK(curthread, pthread); + THR_THREAD_LOCK(curthread, pthread); /* Remove the thread from the mutex queue: */ TAILQ_REMOVE(&mutex->m_queue, pthread, sqe); @@ -1667,14 +1683,9 @@ } /* Make the thread runnable and unlock the scheduling queue: */ - kmbx = _thr_setrunnable_unlocked(pthread); + tid = _thr_setrunnable_unlocked(pthread); - /* Add a preemption point. */ - if ((curthread->kseg == pthread->kseg) && - (pthread->active_priority > curthread->active_priority)) - curthread->critical_yield = 1; - - THR_SCHED_UNLOCK(curthread, pthread); + THR_THREAD_UNLOCK(curthread, pthread); if (mutex->m_owner == pthread) /* We're done; a valid owner was found. */ break; @@ -1686,7 +1697,7 @@ if ((pthread == NULL) && (mutex->m_protocol == PTHREAD_PRIO_INHERIT)) /* This mutex has no priority: */ mutex->m_prio = 0; - return (kmbx); + return (tid); } /*