Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Jan 2005 00:05:43 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 68507 for review
Message-ID:  <200501080005.j0805hhA077675@repoman.freebsd.org>

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

Change 68507 by davidxu@davidxu_tiger on 2005/01/08 00:05:04

	Use low level lock for libc spinlocks, this saves some memory overhead.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_spinlock.c#7 edit

Differences ...

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

@@ -40,20 +40,23 @@
 #include "spinlock.h"
 #include "thr_private.h"
 
-#define	MAX_SPINLOCKS	5
+#define	MAX_SPINLOCKS	20
 
+/*
+ * These data structures are used to trace all spinlocks
+ * in libc.
+ */
 struct spinlock_extra {
 	spinlock_t	*owner;
-	pthread_mutex_t	lock;
 };
 
+static struct umtx		spinlock_static_lock;
+static struct spinlock_extra	extra[MAX_SPINLOCKS];
+static int			spinlock_count;
+static int			initialized;
+
 static void	init_spinlock(spinlock_t *lck);
 
-static pthread_mutex_t		spinlock_static_lock;
-static struct spinlock_extra	extra[MAX_SPINLOCKS];
-static int			spinlock_count = 0;
-static int			initialized = 0;
-
 /*
  * These are for compatability only.  Spinlocks of this type
  * are deprecated.
@@ -62,47 +65,21 @@
 void
 _spinunlock(spinlock_t *lck)
 {
-	struct spinlock_extra *extra;
-
-	extra = (struct spinlock_extra *)lck->fname;
-	_pthread_mutex_unlock(&extra->lock);
+	THR_UMTX_UNLOCK(_get_curthread(), &lck->access_lock);
 }
 
-/*
- * Lock a location for the running thread. Yield to allow other
- * threads to run if this thread is blocked because the lock is
- * not available. Note that this function does not sleep. It
- * assumes that the lock will be available very soon.
- */
 void
 _spinlock(spinlock_t *lck)
 {
-	struct spinlock_extra *extra;
-
 	if (!__isthreaded)
 		PANIC("Spinlock called when not threaded.");
 	if (!initialized)
 		PANIC("Spinlocks not initialized.");
-	/*
-	 * Try to grab the lock and loop if another thread grabs
-	 * it before we do.
-	 */
 	if (lck->fname == NULL)
 		init_spinlock(lck);
-	extra = (struct spinlock_extra *)lck->fname;
-	_pthread_mutex_lock(&extra->lock);
+	THR_UMTX_LOCK(_get_curthread(), &lck->access_lock);
 }
 
-/*
- * Lock a location for the running thread. Yield to allow other
- * threads to run if this thread is blocked because the lock is
- * not available. Note that this function does not sleep. It
- * assumes that the lock will be available very soon.
- *
- * This function checks if the running thread has already locked the
- * location, warns if this occurs and creates a thread dump before
- * returning.
- */
 void
 _spinlock_debug(spinlock_t *lck, char *fname, int lineno)
 {
@@ -112,15 +89,17 @@
 static void
 init_spinlock(spinlock_t *lck)
 {
-	_pthread_mutex_lock(&spinlock_static_lock);
+	static int count = 0;
+
+	THR_UMTX_LOCK(_get_curthread(), &spinlock_static_lock);
 	if ((lck->fname == NULL) && (spinlock_count < MAX_SPINLOCKS)) {
 		lck->fname = (char *)&extra[spinlock_count];
 		extra[spinlock_count].owner = lck;
 		spinlock_count++;
 	}
-	_pthread_mutex_unlock(&spinlock_static_lock);
-	if (lck->fname == NULL)
-		PANIC("Exceeded max spinlocks");
+	THR_UMTX_UNLOCK(_get_curthread(), &spinlock_static_lock);
+	if (lck->fname == NULL && ++count < 5)
+		stderr_debug("Warning: exceeded max spinlocks");
 }
 
 void
@@ -128,17 +107,19 @@
 {
 	int i;
 
+	umtx_init(&spinlock_static_lock);
 	if (initialized != 0) {
-		_mutex_reinit(&spinlock_static_lock);
+		/*
+		 * called after fork() to reset state of libc spin locks,
+		 * it is not quite right since libc may be in inconsistent
+		 * state, resetting the locks to allow current thread to be
+		 * able to hold them may not help things too much, but
+		 * anyway, we do our best.
+		 * it is better to do pthread_atfork in libc.
+		 */
 		for (i = 0; i < spinlock_count; i++)
-			_mutex_reinit(&extra[i].lock);
+			umtx_init((struct umtx *)&extra[i].owner->access_lock);
 	} else {
-		if (_pthread_mutex_init(&spinlock_static_lock, NULL))
-			PANIC("Cannot initialize spinlock_static_lock");
-		for (i = 0; i < MAX_SPINLOCKS; i++) {
-			if (_pthread_mutex_init(&extra[i].lock, NULL))
-				PANIC("Cannot initialize spinlock extra");
-		}
 		initialized = 1;
 	}
 }



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