PERFORCE change 65511 for review
David Xu
davidxu at FreeBSD.org
Fri Nov 19 20:27:48 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=65511
Change 65511 by davidxu at 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);
}
/*
More information about the p4-projects
mailing list