Date: Tue, 21 May 2002 12:38:02 -0700 (PDT) From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 11673 for review Message-ID: <200205211938.g4LJc2u39808@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=11673 Change 11673 by jhb@jhb_laptop on 2002/05/21 12:37:34 Integrate from jhb_lock: - Adaptive mutexes. - Optimize spinlocks to critical sections for UP kernels. - cpu_pause() support for i386. Affected files ... ... //depot/projects/smpng/sys/conf/NOTES#11 integrate ... //depot/projects/smpng/sys/conf/options#24 integrate ... //depot/projects/smpng/sys/kern/kern_mutex.c#29 integrate ... //depot/projects/smpng/sys/sys/mutex.h#27 integrate Differences ... ==== //depot/projects/smpng/sys/conf/NOTES#11 (text+ko) ==== @@ -120,6 +120,11 @@ # Mandatory: options SMP # Symmetric MultiProcessor Kernel +# ADAPTIVE_MUTEXES changes the behavior of blocking mutexes to spin +# if the thread that currently owns the mutex is executing on another +# CPU. +options ADAPTIVE_MUTEXES + # SMP Debugging Options: # # MUTEX_DEBUG enables various extra assertions in the mutex code. ==== //depot/projects/smpng/sys/conf/options#24 (text+ko) ==== @@ -57,6 +57,7 @@ # Miscellaneous options. GEOM opt_geom.h +ADAPTIVE_MUTEXES COMPAT_43 opt_compat.h COMPAT_SUNOS opt_compat.h COMPILING_LINT opt_global.h ==== //depot/projects/smpng/sys/kern/kern_mutex.c#29 (text+ko) ==== @@ -34,6 +34,7 @@ * Machine independent bits of mutex implementation. */ +#include "opt_adaptive_mutexes.h" #include "opt_ddb.h" #include <sys/param.h> @@ -394,7 +395,11 @@ { MPASS(curthread != NULL); +#if defined(SMP) || LOCK_DEBUG > 0 _get_spin_lock(m, curthread, opts, file, line); +#else + critical_enter(); +#endif LOCK_LOG_LOCK("LOCK", &m->mtx_object, opts, m->mtx_recurse, file, line); WITNESS_LOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line); @@ -409,7 +414,11 @@ WITNESS_UNLOCK(&m->mtx_object, opts | LOP_EXCLUSIVE, file, line); LOCK_LOG_LOCK("UNLOCK", &m->mtx_object, opts, m->mtx_recurse, file, line); +#if defined(SMP) || LOCK_DEBUG > 0 _rel_spin_lock(m); +#else + critical_exit(); +#endif } /* @@ -451,6 +460,9 @@ _mtx_lock_sleep(struct mtx *m, int opts, const char *file, int line) { struct thread *td = curthread; +#if defined(SMP) && defined(ADAPTIVE_MUTEXES) + struct thread *owner; +#endif if ((m->mtx_lock & MTX_FLAGMASK) == (uintptr_t)td) { m->mtx_recurse++; @@ -506,6 +518,22 @@ continue; } +#if defined(SMP) && defined(ADAPTIVE_MUTEXES) + /* + * If the current owner of the lock is executing on another + * CPU, spin instead of blocking. + */ + owner = (struct thread *)(v & MTX_FLAGMASK); + if (m != &Giant && owner->td_kse != NULL && + owner->td_kse->ke_oncpu != NOCPU) { + mtx_unlock_spin(&sched_lock); +#ifdef __i386__ + cpu_pause(); +#endif + continue; + } +#endif /* SMP && ADAPTIVE_MUTEXES */ + /* * We definitely must sleep for this lock. */ @@ -594,6 +622,9 @@ /* Give interrupts a chance while we spin. */ critical_exit(); while (m->mtx_lock != MTX_UNOWNED) { +#ifdef __i386__ + cpu_pause(); +#endif if (i++ < 10000000) continue; if (i++ < 60000000) @@ -643,6 +674,15 @@ CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p contested", m); td1 = TAILQ_FIRST(&m->mtx_blocked); +#if defined(SMP) && defined(ADAPTIVE_MUTEXES) + if (td1 == NULL) { + _release_lock_quick(m); + if (LOCK_LOG_TEST(&m->mtx_object, opts)) + CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p no sleepers", m); + mtx_unlock_spin(&sched_lock); + return; + } +#endif MPASS(td->td_proc->p_magic == P_MAGIC); MPASS(td1->td_proc->p_magic == P_MAGIC); ==== //depot/projects/smpng/sys/sys/mutex.h#27 (text+ko) ==== @@ -258,16 +258,21 @@ _mtx_lock_spin_flags((m), (opts), LOCK_FILE, LOCK_LINE) #define mtx_unlock_spin_flags(m, opts) \ _mtx_unlock_spin_flags((m), (opts), LOCK_FILE, LOCK_LINE) -#else +#else /* LOCK_DEBUG == 0 */ #define mtx_lock_flags(m, opts) \ _get_sleep_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE) #define mtx_unlock_flags(m, opts) \ _rel_sleep_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE) +#ifdef SMP #define mtx_lock_spin_flags(m, opts) \ _get_spin_lock((m), curthread, (opts), LOCK_FILE, LOCK_LINE) #define mtx_unlock_spin_flags(m, opts) \ _rel_spin_lock((m)) -#endif +#else /* SMP */ +#define mtx_lock_spin_flags(m, opts) critical_enter() +#define mtx_unlock_spin_flags(m, opts) critical_exit() +#endif /* SMP */ +#endif /* LOCK_DEBUG */ #define mtx_trylock_flags(m, opts) \ _mtx_trylock((m), (opts), LOCK_FILE, LOCK_LINE) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200205211938.g4LJc2u39808>