summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-10-29 21:58:08 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-10-29 21:58:08 +0000
commit86276cc3f3ba9e9ba66960b6bee5eb210b8fe53f (patch)
tree0ab22c4840af2d75aa108d8a0aa4b28d909083af /sys/arch
parent6113be1aa712fa5b8de93699ffaf947a4325907c (diff)
On UltraSPARC T1/T2, block the current strand while spinning in the hope
other strands can do some useful work. Idea stolen from Linux. Results in a small, but measurable speedup doing a kernel build and reduces the system time by almost 10%.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sparc64/sparc64/lock_machdep.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/sys/arch/sparc64/sparc64/lock_machdep.c b/sys/arch/sparc64/sparc64/lock_machdep.c
index 08b07682b3e..357873d2f39 100644
--- a/sys/arch/sparc64/sparc64/lock_machdep.c
+++ b/sys/arch/sparc64/sparc64/lock_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lock_machdep.c,v 1.2 2012/08/30 20:57:00 kettenis Exp $ */
+/* $OpenBSD: lock_machdep.c,v 1.3 2012/10/29 21:58:07 kettenis Exp $ */
/*
* Copyright (c) 2007 Artur Grabowski <art@openbsd.org>
@@ -43,14 +43,33 @@ __mp_lock_init(struct __mp_lock *lock)
extern int __mp_lock_spinout;
#endif
+/*
+ * On processors with multiple threads we force a thread switch.
+ *
+ * On UltraSPARC T2 and its successors, the optimal way to do this
+ * seems to be to do three nop reads of %ccr. This works on
+ * UltraSPARC T1 as well, even though three nop casx operations seem
+ * to be slightly more optimal. Since these instructions are
+ * effectively nops, executing them on earlier non-CMT processors is
+ * harmless, so we make this the default.
+ *
+ * On SPARC64 VI and it successors we execute the processor-specific
+ * sleep instruction.
+ */
static __inline void
__mp_lock_spin_hook(void)
{
__asm __volatile(
- "999: nop \n"
+ "999: rd %%ccr, %%g0 \n"
+ " rd %%ccr, %%g0 \n"
+ " rd %%ccr, %%g0 \n"
" .section .sun4u_mtp_patch, \"ax\" \n"
" .word 999b \n"
" .word 0x81b01060 ! sleep \n"
+ " .word 999b + 4 \n"
+ " nop \n"
+ " .word 999b + 8 \n"
+ " nop \n"
" .previous \n"
: : : "memory");
}