PERFORCE change 68507 for review
David Xu
davidxu at FreeBSD.org
Fri Jan 7 16:05:45 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=68507
Change 68507 by davidxu at 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;
}
}
More information about the p4-projects
mailing list