PERFORCE change 67346 for review

David Xu davidxu at FreeBSD.org
Sun Dec 19 00:12:08 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=67346

Change 67346 by davidxu at davidxu_tiger on 2004/12/19 08:11:50

	simplify some mutex locking code, this causes performance of super-smack
	test to be increased about 15%.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/Makefile#5 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/sys/lock.h#4 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#4 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_kern.c#4 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_mutex.c#4 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#6 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_spinlock.c#3 edit

Differences ...

==== //depot/projects/davidxu_thread/src/lib/libthread/Makefile#5 (text+ko) ====


==== //depot/projects/davidxu_thread/src/lib/libthread/sys/lock.h#4 (text+ko) ====


==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#4 (text+ko) ====

@@ -88,28 +88,14 @@
 		/* Child process */
 		errsave = errno;
 
-		/* clear aother thread locked us. */
-		_UMTX_REINIT(&curthread->lock);
-		thr_self(&curthread->tid);
+		_thr_mutex_reinit(&_thr_atfork_mutex);
 
-		/* reinitialize libc spinlocks, this includes __malloc_lock. */
-		_thr_spinlock_init();
-
-		/*
-		 * reinitialize all mutexes the curthread owns, these include
-		 * _thr_fork_mutex.
-		 */
-		TAILQ_FOREACH(m, &curthread->mutexq, m_qe) {
-			_thr_mutex_reinit(curthread, &m);
-		}
 		/* Reinitialize lib kernel. */
 		_thr_single_thread(curthread);
 
 		/* Restore signal mask. */ 
 		__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
 
-		_pthread_mutex_unlock(&_thr_atfork_mutex);
-
 		/* Run down atfork child handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
 			if (af->child != NULL)

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_kern.c#4 (text+ko) ====

@@ -124,6 +124,14 @@
 void
 _thr_single_thread(struct pthread *curthread)
 {
+	curthread->cancelflags &= ~THR_CANCELLING;
+	/* clear aother thread locked us. */
+	_UMTX_REINIT(&curthread->lock);
+	thr_self(&curthread->tid);
+	/* reinitialize libc spinlocks, this includes __malloc_lock. */
+	_thr_spinlock_init();
+	TAILQ_INIT(&curthread->mutexq);
+	curthread->priority_mutex_count = 0;
 	_libpthread_init(curthread);
 #if 0	
 	if (__isthreaded) {

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_mutex.c#4 (text+ko) ====

@@ -74,8 +74,7 @@
 /*
  * Prototypes
  */
-static long		mutex_handoff(struct pthread *,
-			    struct pthread_mutex *);
+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);
 static int		mutex_unlock_common(pthread_mutex_t *, int);
@@ -134,7 +133,7 @@
 
 	/* Check mutex protocol: */
 	else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
-	    ((*mutex_attr)->m_protocol > PTHREAD_MUTEX_RECURSIVE))
+	    ((*mutex_attr)->m_protocol > PTHREAD_PRIO_PROTECT))
 		/* Return an invalid argument error: */
 		ret = EINVAL;
 
@@ -203,16 +202,13 @@
 }
 
 void
-_thr_mutex_reinit(struct pthread *curthread, pthread_mutex_t *mutex)
+_thr_mutex_reinit(pthread_mutex_t *mutex)
 {
 	_UMTX_REINIT(&(*mutex)->m_lock);
 	TAILQ_INIT(&(*mutex)->m_queue);
-	if (curthread == NULL || 
-	    (*mutex)->m_owner != curthread) {
-		MUTEX_INIT_LINK(*mutex);
-		(*mutex)->m_owner = NULL;
-		(*mutex)->m_count = 0;
-	}
+	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;
@@ -221,16 +217,12 @@
 int
 _pthread_mutex_destroy(pthread_mutex_t *mutex)
 {
-	struct pthread	*curthread = _get_curthread();
 	pthread_mutex_t m;
 	int ret = 0;
 
 	if (mutex == NULL || *mutex == NULL)
 		ret = EINVAL;
 	else {
-		/* Lock the mutex structure: */
-		THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock);
-
 		/*
 		 * Check to see if this mutex is in use:
 		 */
@@ -238,9 +230,6 @@
 		    (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
 		    ((*mutex)->m_refcount != 0)) {
 			ret = EBUSY;
-
-			/* Unlock the mutex structure: */
-			THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock);
 		} else {
 			/*
 			 * Save a pointer to the mutex so it can be free'd
@@ -249,9 +238,6 @@
 			m = *mutex;
 			*mutex = NULL;
 
-			/* Unlock the mutex structure: */
-			THR_LOCK_RELEASE(curthread, &m->m_lock);
-
 			/*
 			 * Free the memory allocated for the mutex
 			 * structure:
@@ -307,6 +293,28 @@
 	THR_ASSERT((mutex != NULL) && (*mutex != NULL),
 	    "Uninitialized mutex in pthread_mutex_trylock_basic");
 
+	if ((*mutex)->m_protocol == PTHREAD_PRIO_NONE) {
+		ret = umtx_trylock(&(*mutex)->m_lock, curthread->tid);
+		if (ret == 0) {
+			(*mutex)->m_owner = curthread;
+			/*
+			 * XXX there should be a separated list for owned mutex,
+			 * separated it from priority mutex list
+			 */
+#if 0
+			/* Add to the list of owned mutexes: */
+			MUTEX_ASSERT_NOT_OWNED(*mutex);
+			TAILQ_INSERT_TAIL(&curthread->mutexq,
+			    (*mutex), m_qe);
+#endif
+		} else if ((*mutex)->m_owner == curthread)
+			ret = mutex_self_trylock(curthread, *mutex);
+		else
+			ret = EBUSY;
+
+		return (ret);
+	}
+
 	/* Lock the mutex structure: */
 	THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock);
 
@@ -322,24 +330,6 @@
 
 	/* Process according to mutex type: */
 	switch ((*mutex)->m_protocol) {
-	/* Default POSIX mutex: */
-	case PTHREAD_PRIO_NONE:	
-		/* Check if this mutex is not locked: */
-		if ((*mutex)->m_owner == NULL) {
-			/* Lock the mutex for the running thread: */
-			(*mutex)->m_owner = curthread;
-
-			/* Add to the list of owned mutexes: */
-			MUTEX_ASSERT_NOT_OWNED(*mutex);
-			TAILQ_INSERT_TAIL(&curthread->mutexq,
-			    (*mutex), m_qe);
-		} else if ((*mutex)->m_owner == curthread)
-			ret = mutex_self_trylock(curthread, *mutex);
-		else
-			/* Return a busy error: */
-			ret = EBUSY;
-		break;
-
 	/* POSIX priority inheritence mutex: */
 	case PTHREAD_PRIO_INHERIT:
 		/* Check if this mutex is not locked: */
@@ -472,6 +462,47 @@
 	THR_ASSERT((m != NULL) && (*m != NULL),
 	    "Uninitialized mutex in mutex_lock_common");
 
+	if ((*m)->m_protocol == PTHREAD_PRIO_NONE) {
+		/* Default POSIX mutex: */
+		ret = umtx_trylock(&(*m)->m_lock, curthread->tid);
+		if (ret == 0) {
+			(*m)->m_owner = curthread;
+			/*
+			 * XXX there should be a separated list for owned mutex,
+			 * separated it from priority mutex list
+			 */
+#if 0
+			/* Add to the list of owned mutexes: */
+			MUTEX_ASSERT_NOT_OWNED(*m);
+			TAILQ_INSERT_TAIL(&curthread->mutexq,
+			    (*m), m_qe);
+#endif
+		} else if ((*m)->m_owner == curthread &&
+			   !((*m)->m_type == PTHREAD_MUTEX_NORMAL &&
+			     abstime != NULL)) {
+			ret = mutex_self_lock(curthread, *m);
+		} else {
+			if (abstime != NULL) {
+				ret = umtx_timedlock(&(*m)->m_lock, curthread->tid,
+						(struct timespec *)abstime);
+				if (ret == EAGAIN || ret == EINTR)
+					ret = ETIMEDOUT;
+			} else {
+				ret = _UMTX_LOCK(&(*m)->m_lock, curthread->tid);
+			}
+			if (ret == 0) {
+				(*m)->m_owner = curthread;
+#if 0
+				/* Add to the list of owned mutexes: */
+				MUTEX_ASSERT_NOT_OWNED(*m);
+				TAILQ_INSERT_TAIL(&curthread->mutexq,
+				    (*m), m_qe);
+#endif
+			}
+		}
+		return (ret);
+	}
+
 	if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
 	    abstime->tv_nsec >= 1000000000))
 		return (EINVAL);
@@ -505,68 +536,6 @@
 
 		/* Process according to mutex type: */
 		switch ((*m)->m_protocol) {
-		/* Default POSIX mutex: */
-		case PTHREAD_PRIO_NONE:
-			if ((*m)->m_owner == NULL) {
-				/* Lock the mutex for this thread: */
-				(*m)->m_owner = curthread;
-
-				/* Add to the list of owned mutexes: */
-				MUTEX_ASSERT_NOT_OWNED(*m);
-				TAILQ_INSERT_TAIL(&curthread->mutexq,
-				    (*m), m_qe);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else if ((*m)->m_owner == curthread) {
-				ret = mutex_self_lock(curthread, *m);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else {
-				/* Set the wakeup time: */
-				if (abstime) {
-					curthread->wakeup_time.tv_sec =
-						abstime->tv_sec;
-					curthread->wakeup_time.tv_nsec =
-						abstime->tv_nsec;
-				}
-
-				/*
-				 * Join the queue of threads waiting to lock
-				 * the mutex and save a pointer to the mutex.
-				 */
-				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_LOCK_SWITCH(curthread);
-				THR_SET_STATE(curthread, PS_MUTEX_WAIT);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-
-				/* Schedule the next thread: */
-				_thr_sched_switch_unlocked(curthread);
-
-				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;
-
 		/* POSIX priority inheritence mutex: */
 		case PTHREAD_PRIO_INHERIT:
 			/* Check if this mutex is not locked: */
@@ -907,11 +876,8 @@
 	int	ret;
 
 	curthread = _get_curthread();
-	if ((ret = _pthread_mutex_lock(m)) == 0) {
-		THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
+	if ((ret = _pthread_mutex_lock(m)) == 0)
 		(*m)->m_refcount--;
-		THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-	}
 	return (ret);
 }
 
@@ -994,13 +960,7 @@
 	if (m == NULL || *m == NULL)
 		ret = EINVAL;
 	else {
-		/* Lock the mutex structure: */
-		THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
-
-		/* Process according to mutex type: */
-		switch ((*m)->m_protocol) {
-		/* Default POSIX mutex: */
-		case PTHREAD_PRIO_NONE:
+		if ((*m)->m_protocol == PTHREAD_PRIO_NONE) {
 			/*
 			 * Check if the running thread is not the owner of the
 			 * mutex:
@@ -1008,30 +968,48 @@
 			if ((*m)->m_owner != curthread)
 				ret = EPERM;
 			else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
-			    ((*m)->m_count > 0))
+			         ((*m)->m_count > 0)) {
 				/* Decrement the count: */
 				(*m)->m_count--;
-			else {
+				if (add_reference)
+					(*m)->m_refcount++;
+			} else {
 				/*
 				 * Clear the count in case this is a recursive
 				 * mutex.
 				 */
 				(*m)->m_count = 0;
-
+				(*m)->m_owner = NULL;
+				/*
+				 * XXX there should be a separated list
+				 * for owned mutex, separated it from
+				 * priority mutex list
+				 */
+#if 0
 				/* Remove the mutex from the threads queue. */
 				MUTEX_ASSERT_IS_OWNED(*m);
 				TAILQ_REMOVE(&(*m)->m_owner->mutexq,
 				    (*m), m_qe);
 				MUTEX_INIT_LINK(*m);
-
+#endif
+				if (add_reference)
+					(*m)->m_refcount++;
 				/*
 				 * Hand off the mutex to the next waiting
 				 * thread:
 				 */
-				tid = mutex_handoff(curthread, *m);
+				ret = umtx_unlock(&(*m)->m_lock,
+						  curthread->tid);
+				/* XXX decrease refcount if failed ? */
 			}
-			break;
+			return (ret);
+		}
+
+		/* Lock the mutex structure: */
+		THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
 
+		/* Process according to mutex type: */
+		switch ((*m)->m_protocol) {
 		/* POSIX priority inheritence mutex: */
 		case PTHREAD_PRIO_INHERIT:
 			/*

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#6 (text+ko) ====

@@ -776,7 +776,7 @@
 struct pthread *_thr_alloc(struct pthread *);
 void	_thr_exit(char *, int, char *);
 void	_thr_exit_cleanup(void);
-void	_thr_mutex_reinit(struct pthread *, pthread_mutex_t *);
+void	_thr_mutex_reinit(pthread_mutex_t *);
 int	_thr_ref_add(struct pthread *, struct pthread *, int);
 void	_thr_ref_delete(struct pthread *, struct pthread *);
 void	_thr_rtld_init(void);

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_spinlock.c#3 (text+ko) ====

@@ -129,9 +129,9 @@
 	int i;
 
 	if (initialized != 0) {
-		_thr_mutex_reinit(_get_curthread(), &spinlock_static_lock);
+		_thr_mutex_reinit(&spinlock_static_lock);
 		for (i = 0; i < spinlock_count; i++)
-			_thr_mutex_reinit(_get_curthread(), &extra[i].lock);
+			_thr_mutex_reinit(&extra[i].lock);
 	} else {
 		if (pthread_mutex_init(&spinlock_static_lock, NULL))
 			PANIC("Cannot initialize spinlock_static_lock");


More information about the p4-projects mailing list