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