From owner-p4-projects@FreeBSD.ORG Sat Jan 8 00:05:44 2005 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8457916A4D0; Sat, 8 Jan 2005 00:05:44 +0000 (GMT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 47BC116A4CE for ; Sat, 8 Jan 2005 00:05:44 +0000 (GMT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 148AD43D31 for ; Sat, 8 Jan 2005 00:05:44 +0000 (GMT) (envelope-from davidxu@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j0805hUj077678 for ; Sat, 8 Jan 2005 00:05:43 GMT (envelope-from davidxu@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j0805hhA077675 for perforce@freebsd.org; Sat, 8 Jan 2005 00:05:43 GMT (envelope-from davidxu@freebsd.org) Date: Sat, 8 Jan 2005 00:05:43 GMT Message-Id: <200501080005.j0805hhA077675@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to davidxu@freebsd.org using -f From: David Xu To: Perforce Change Reviews Subject: PERFORCE change 68507 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Jan 2005 00:05:45 -0000 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; } }