Skip site navigation (1)Skip section navigation (2)
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>