Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Jan 2005 05:14:31 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 68455 for review
Message-ID:  <200501070514.j075EV6h094556@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=68455

Change 68455 by davidxu@davidxu_celeron on 2005/01/07 05:13:46

	use atomic operation, remove static initializing lock.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_rwlock.c#3 edit

Differences ...

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

@@ -51,52 +51,9 @@
 /*
  * Prototypes
  */
-static int init_static(pthread_rwlock_t *rwlock);
-
 
 static int
-init_static(pthread_rwlock_t *rwlock)
-{
-	struct pthread *thread = _get_curthread();
-	int ret;
-
-	THR_LOCK_ACQUIRE(thread, &_rwlock_static_lock);
-
-	if (*rwlock == NULL)
-		ret = _pthread_rwlock_init(rwlock, NULL);
-	else
-		ret = 0;
-
-	THR_LOCK_RELEASE(thread, &_rwlock_static_lock);
-	return (ret);
-}
-
-int
-_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
-{
-	int ret;
-
-	if (rwlock == NULL)
-		ret = EINVAL;
-	else {
-		pthread_rwlock_t prwlock;
-
-		prwlock = *rwlock;
-
-		_pthread_mutex_destroy(&prwlock->lock);
-		_pthread_cond_destroy(&prwlock->read_signal);
-		_pthread_cond_destroy(&prwlock->write_signal);
-		free(prwlock);
-
-		*rwlock = NULL;
-
-		ret = 0;
-	}
-	return (ret);
-}
-
-int
-_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
 {
 	pthread_rwlock_t prwlock;
 	int ret;
@@ -129,8 +86,12 @@
 				/* success */
 				prwlock->state = 0;
 				prwlock->blocked_writers = 0;
-
-				*rwlock = prwlock;
+				if (!atomic_cmpset_acq_ptr(rwlock, NULL, prwlock)) {
+					/* we lost a race, it was already initialized */
+					_pthread_cond_destroy(&prwlock->read_signal);
+					_pthread_mutex_destroy(&prwlock->lock);
+					free(prwlock);
+				}
 			}
 		}
 	}
@@ -138,6 +99,37 @@
 	return (ret);
 }
 
+int
+_pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
+{
+	int ret;
+
+	if (rwlock == NULL)
+		ret = EINVAL;
+	else {
+		pthread_rwlock_t prwlock;
+
+		prwlock = *rwlock;
+
+		_pthread_mutex_destroy(&prwlock->lock);
+		_pthread_cond_destroy(&prwlock->read_signal);
+		_pthread_cond_destroy(&prwlock->write_signal);
+		free(prwlock);
+
+		*rwlock = NULL;
+
+		ret = 0;
+	}
+	return (ret);
+}
+
+int
+_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+{
+	*rwlock = NULL;
+	return (rwlock_init(rwlock, attr));
+}
+
 static int
 rwlock_rdlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
 {
@@ -152,7 +144,7 @@
 
 	/* check for static initialization */
 	if (prwlock == NULL) {
-		if ((ret = init_static(rwlock)) != 0)
+		if ((ret = rwlock_init(rwlock, NULL)) != 0)
 			return (ret);
 
 		prwlock = *rwlock;
@@ -244,7 +236,7 @@
 
 	/* check for static initialization */
 	if (prwlock == NULL) {
-		if ((ret = init_static(rwlock)) != 0)
+		if ((ret = rwlock_init(rwlock, NULL)) != 0)
 			return (ret);
 
 		prwlock = *rwlock;
@@ -289,7 +281,7 @@
 
 	/* check for static initialization */
 	if (prwlock == NULL) {
-		if ((ret = init_static(rwlock)) != 0)
+		if ((ret = rwlock_init(rwlock, NULL)) != 0)
 			return (ret);
 
 		prwlock = *rwlock;
@@ -367,7 +359,7 @@
 
 	/* check for static initialization */
 	if (prwlock == NULL) {
-		if ((ret = init_static(rwlock)) != 0)
+		if ((ret = rwlock_init(rwlock, NULL)) != 0)
 			return (ret);
 
 		prwlock = *rwlock;



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