Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Nov 2010 05:54:05 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r215080 - in user/davidxu/libthr: include lib/libthr lib/libthr/thread sys/sys
Message-ID:  <201011100554.oAA5s5RF086798@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davidxu
Date: Wed Nov 10 05:54:05 2010
New Revision: 215080
URL: http://svn.freebsd.org/changeset/base/215080

Log:
  Convert pthread_spinlock from pointer to structure.

Modified:
  user/davidxu/libthr/include/pthread.h
  user/davidxu/libthr/lib/libthr/pthread.map
  user/davidxu/libthr/lib/libthr/thread/thr_private.h
  user/davidxu/libthr/lib/libthr/thread/thr_pspinlock.c
  user/davidxu/libthr/sys/sys/_pthreadtypes.h

Modified: user/davidxu/libthr/include/pthread.h
==============================================================================
--- user/davidxu/libthr/include/pthread.h	Wed Nov 10 05:49:44 2010	(r215079)
+++ user/davidxu/libthr/include/pthread.h	Wed Nov 10 05:54:05 2010	(r215080)
@@ -203,6 +203,10 @@ struct pthread_barrier {
 	__uint32_t	__waiters;
 };
 
+struct pthread_spinlock {
+	__uint32_t	__lock;
+};
+
 /*
  * Thread function prototype definitions:
  */

Modified: user/davidxu/libthr/lib/libthr/pthread.map
==============================================================================
--- user/davidxu/libthr/lib/libthr/pthread.map	Wed Nov 10 05:49:44 2010	(r215079)
+++ user/davidxu/libthr/lib/libthr/pthread.map	Wed Nov 10 05:54:05 2010	(r215080)
@@ -101,11 +101,6 @@ FBSD_1.0 {
 	pthread_setspecific;
 	pthread_sigmask;
 	pthread_single_np;
-	pthread_spin_destroy;
-	pthread_spin_init;
-	pthread_spin_lock;
-	pthread_spin_trylock;
-	pthread_spin_unlock;
 	pthread_suspend_all_np;
 	pthread_suspend_np;
 	pthread_switch_add_np;
@@ -398,6 +393,11 @@ FBSD_1.2 {
 	pthread_mutex_timedlock;
 	pthread_mutex_trylock;
 	pthread_mutex_unlock;
+	pthread_spin_destroy;
+	pthread_spin_init;
+	pthread_spin_lock;
+	pthread_spin_trylock;
+	pthread_spin_unlock;
 	pthread_rwlock_destroy;
 	pthread_rwlock_init;
 	pthread_rwlock_rdlock;

Modified: user/davidxu/libthr/lib/libthr/thread/thr_private.h
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_private.h	Wed Nov 10 05:49:44 2010	(r215079)
+++ user/davidxu/libthr/lib/libthr/thread/thr_private.h	Wed Nov 10 05:54:05 2010	(r215080)
@@ -167,10 +167,6 @@ struct pthread_barrierattr {
 	int		pshared;
 };
 
-struct pthread_spinlock {
-	struct umutex	s_lock;
-};
-
 /*
  * Cleanup definitions.
  */

Modified: user/davidxu/libthr/lib/libthr/thread/thr_pspinlock.c
==============================================================================
--- user/davidxu/libthr/lib/libthr/thread/thr_pspinlock.c	Wed Nov 10 05:49:44 2010	(r215079)
+++ user/davidxu/libthr/lib/libthr/thread/thr_pspinlock.c	Wed Nov 10 05:54:05 2010	(r215080)
@@ -34,105 +34,135 @@
 
 #include "thr_private.h"
 
-#define SPIN_COUNT 100000
-
 __weak_reference(_pthread_spin_init, pthread_spin_init);
 __weak_reference(_pthread_spin_destroy, pthread_spin_destroy);
 __weak_reference(_pthread_spin_trylock, pthread_spin_trylock);
 __weak_reference(_pthread_spin_lock, pthread_spin_lock);
 __weak_reference(_pthread_spin_unlock, pthread_spin_unlock);
 
+typedef pthread_spinlock_t *pthread_spinlock_old_t;
+int _pthread_spin_destroy_1_0(pthread_spinlock_old_t *);
+int _pthread_spin_init_1_0(pthread_spinlock_old_t *, int);
+int _pthread_spin_lock_1_0(pthread_spinlock_old_t *);
+int _pthread_spin_trylock_1_0(pthread_spinlock_old_t *);
+int _pthread_spin_unlock_1_0(pthread_spinlock_old_t *);
+
 int
-_pthread_spin_init(pthread_spinlock_t *lock, int pshared)
+_pthread_spin_init(pthread_spinlock_t *lckp, int pshared)
 {
-	struct pthread_spinlock	*lck;
-	int ret;
-
-	if (lock == NULL || pshared != PTHREAD_PROCESS_PRIVATE)
-		ret = EINVAL;
-	else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL)
-		ret = ENOMEM;
-	else {
-		_thr_umutex_init(&lck->s_lock);
-		*lock = lck;
-		ret = 0;
-	}
+	if (pshared != PTHREAD_PROCESS_PRIVATE &&
+	    pshared != PTHREAD_PROCESS_SHARED)
+		return (EINVAL);
+	lckp->__lock = 0;
+	return (0);
+}
 
-	return (ret);
+int
+_pthread_spin_destroy(pthread_spinlock_t *lckp)
+{
+	/* Nothing to do. */
+	return (0);
 }
 
 int
-_pthread_spin_destroy(pthread_spinlock_t *lock)
+_pthread_spin_trylock(pthread_spinlock_t *lckp)
 {
-	int ret;
+	if (atomic_cmpset_acq_32(&lckp->__lock, 0, 1))
+		return (0);
+	return (EBUSY);
+}
 
-	if (lock == NULL || *lock == NULL)
-		ret = EINVAL;
-	else {
-		free(*lock);
-		*lock = NULL;
-		ret = 0;
+int
+_pthread_spin_lock(pthread_spinlock_t *lckp)
+{
+	/* 
+	 * Nothing has been checked, the lock should be
+	 * as fast as possible.
+	 */
+	if (atomic_cmpset_acq_32(&lckp->__lock, 0, 1))
+		return (0);
+	for (;;) {
+		if (*(volatile int32_t *)&(lckp->__lock) == 0)
+			if (atomic_cmpset_acq_32(&lckp->__lock, 0, 1))
+				break;
+		if (!_thr_is_smp)
+			_pthread_yield();
+		else
+			CPU_SPINWAIT;
 	}
+	return (0);
+}
+
+int
+_pthread_spin_unlock(pthread_spinlock_t *lckp)
+{
+	lckp->__lock = 0;
+	wmb();
+	return (0);
+}
+
+int
+_pthread_spin_init_1_0(pthread_spinlock_old_t *lckpp, int pshared)
+{
+	pthread_spinlock_t *lckp;
 
-	return (ret);
+	if (pshared != PTHREAD_PROCESS_PRIVATE &&
+	    pshared != PTHREAD_PROCESS_SHARED)
+		return (EINVAL);
+	
+	lckp = malloc(sizeof(pthread_spinlock_t));
+	if (lckp == NULL)
+		return (ENOMEM);
+	lckp->__lock = 0;
+	*lckpp = lckp;
+	return (0);
 }
 
 int
-_pthread_spin_trylock(pthread_spinlock_t *lock)
+_pthread_spin_destroy_1_0(pthread_spinlock_old_t *lckpp)
 {
-	struct pthread *curthread = _get_curthread();
-	struct pthread_spinlock	*lck;
-	int ret;
+	pthread_spinlock_t *lckp = *lckpp;
 
-	if (lock == NULL || (lck = *lock) == NULL)
-		ret = EINVAL;
-	else
-		ret = THR_UMUTEX_TRYLOCK(curthread, &lck->s_lock);
-	return (ret);
+	if (lckp != NULL) {
+		free(lckp);
+		*lckpp = NULL;
+		return (0);
+	} else
+		return (EINVAL);
 }
 
 int
-_pthread_spin_lock(pthread_spinlock_t *lock)
+_pthread_spin_trylock_1_0(pthread_spinlock_old_t *lckpp)
 {
-	struct pthread *curthread = _get_curthread();
-	struct pthread_spinlock	*lck;
-	int ret, count;
+	pthread_spinlock_t *lckp = *lckpp;
 
-	if (lock == NULL || (lck = *lock) == NULL)
-		ret = EINVAL;
-	else {
-		count = SPIN_COUNT;
-		while ((ret = THR_UMUTEX_TRYLOCK(curthread, &lck->s_lock)) != 0) {
-			while (lck->s_lock.m_owner) {
-				if (!_thr_is_smp) {
-					_pthread_yield();
-				} else {
-					CPU_SPINWAIT;
+	if (lckp == NULL)
+		return (EINVAL);
+	return _pthread_spin_trylock(lckp);
+}
 
-					if (--count <= 0) {
-						count = SPIN_COUNT;
-						_pthread_yield();
-					}
-				}
-			}
-		}
-		ret = 0;
-	}
+int
+_pthread_spin_lock_1_0(pthread_spinlock_old_t *lckpp)
+{
+	pthread_spinlock_t *lckp = *lckpp;
 
-	return (ret);
+	if (lckp == NULL)
+		return (EINVAL);
+	return _pthread_spin_lock(lckp);
 }
 
 int
-_pthread_spin_unlock(pthread_spinlock_t *lock)
+_pthread_spin_unlock_1_0(pthread_spinlock_old_t *lckpp)
 {
-	struct pthread *curthread = _get_curthread();
-	struct pthread_spinlock	*lck;
-	int ret;
+	pthread_spinlock_t *lckp = *lckpp;
 
-	if (lock == NULL || (lck = *lock) == NULL)
-		ret = EINVAL;
-	else {
-		ret = THR_UMUTEX_UNLOCK(curthread, &lck->s_lock);
-	}
-	return (ret);
+	if (lckp == NULL)
+		return (EINVAL);
+	return _pthread_spin_unlock(lckp);
 }
+
+FB10_COMPAT(_pthread_spin_destroy_1_0, pthread_spin_destroy);
+FB10_COMPAT(_pthread_spin_init_1_0, pthread_spin_init);
+FB10_COMPAT(_pthread_spin_lock_1_0, pthread_spin_lock);
+FB10_COMPAT(_pthread_spin_trylock_1_0, pthread_spin_trylock);
+FB10_COMPAT(_pthread_spin_unlock_1_0, pthread_spin_unlock);

Modified: user/davidxu/libthr/sys/sys/_pthreadtypes.h
==============================================================================
--- user/davidxu/libthr/sys/sys/_pthreadtypes.h	Wed Nov 10 05:49:44 2010	(r215079)
+++ user/davidxu/libthr/sys/sys/_pthreadtypes.h	Wed Nov 10 05:54:05 2010	(r215080)
@@ -76,7 +76,7 @@ typedef struct	pthread_rwlock		pthread_r
 typedef struct	pthread_rwlockattr	*pthread_rwlockattr_t;
 typedef struct	pthread_barrier		pthread_barrier_t;
 typedef struct	pthread_barrierattr	*pthread_barrierattr_t;
-typedef struct	pthread_spinlock	*pthread_spinlock_t;
+typedef struct	pthread_spinlock	pthread_spinlock_t;
 
 /*
  * Additional type definitions:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011100554.oAA5s5RF086798>