diff options
Diffstat (limited to 'usr/src/uts/intel')
-rw-r--r-- | usr/src/uts/intel/ia32/ml/lock_prim.s | 101 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/mutex_impl.h | 30 |
2 files changed, 125 insertions, 6 deletions
diff --git a/usr/src/uts/intel/ia32/ml/lock_prim.s b/usr/src/uts/intel/ia32/ml/lock_prim.s index 8dc51e3eeb..884ca02de8 100644 --- a/usr/src/uts/intel/ia32/ml/lock_prim.s +++ b/usr/src/uts/intel/ia32/ml/lock_prim.s @@ -30,11 +30,11 @@ #include <sys/thread.h> #include <sys/cpuvar.h> #include <vm/page.h> -#include <sys/mutex_impl.h> #else /* __lint */ #include "assym.h" #endif /* __lint */ +#include <sys/mutex_impl.h> #include <sys/asm_linkage.h> #include <sys/asm_misc.h> #include <sys/regset.h> @@ -665,6 +665,34 @@ mutex_exit(kmutex_t *lp) ret SET_SIZE(mutex_adaptive_tryenter) + .globl mutex_owner_running_critical_start + + ENTRY(mutex_owner_running) +mutex_owner_running_critical_start: + movq (%rdi), %r11 /* get owner field */ + andq $MUTEX_THREAD, %r11 /* remove waiters bit */ + cmpq $0, %r11 /* if free, skip */ + je 1f /* go return 0 */ + movq T_CPU(%r11), %r8 /* get owner->t_cpu */ + movq CPU_THREAD(%r8), %r9 /* get t_cpu->cpu_thread */ +.mutex_owner_running_critical_end: + cmpq %r11, %r9 /* owner == running thread? */ + je 2f /* yes, go return cpu */ +1: + xorq %rax, %rax /* return 0 */ + ret +2: + movq %r8, %rax /* return cpu */ + ret + SET_SIZE(mutex_owner_running) + + .globl mutex_owner_running_critical_size + .type mutex_owner_running_critical_size, @object + .align CPTRSIZE +mutex_owner_running_critical_size: + .quad .mutex_owner_running_critical_end - mutex_owner_running_critical_start + SET_SIZE(mutex_owner_running_critical_size) + .globl mutex_exit_critical_start ENTRY(mutex_exit) @@ -806,7 +834,36 @@ mutex_exit_critical_size: ret SET_SIZE(mutex_adaptive_tryenter) - .globl mutex_exit_critical_size + .globl mutex_owner_running_critical_start + + ENTRY(mutex_owner_running) +mutex_owner_running_critical_start: + movl 4(%esp), %eax /* get owner field */ + movl (%eax), %eax + andl $MUTEX_THREAD, %eax /* remove waiters bit */ + cmpl $0, %eax /* if free, skip */ + je 1f /* go return 0 */ + movl T_CPU(%eax), %ecx /* get owner->t_cpu */ + movl CPU_THREAD(%ecx), %edx /* get t_cpu->cpu_thread */ +.mutex_owner_running_critical_end: + cmpl %eax, %edx /* owner == running thread? */ + je 2f /* yes, go return cpu */ +1: + xorl %eax, %eax /* return 0 */ + ret +2: + movl %ecx, %eax /* return cpu */ + ret + + SET_SIZE(mutex_owner_running) + + .globl mutex_owner_running_critical_size + .type mutex_owner_running_critical_size, @object + .align CPTRSIZE +mutex_owner_running_critical_size: + .long .mutex_owner_running_critical_end - mutex_owner_running_critical_start + SET_SIZE(mutex_owner_running_critical_size) + .globl mutex_exit_critical_start ENTRY(mutex_exit) @@ -1398,3 +1455,43 @@ thread_onproc(kthread_id_t t, cpu_t *cp) #endif /* !__amd64 */ #endif /* __lint */ + +/* + * mutex_delay_default(void) + * Spins for approx a few hundred processor cycles and returns to caller. + */ + +#if defined(lint) || defined(__lint) + +void +mutex_delay_default(void) +{} + +#else /* __lint */ + +#if defined(__amd64) + + ENTRY(mutex_delay_default) + movq $92,%r11 +0: decq %r11 + jg 0b + ret + SET_SIZE(mutex_delay_default) + +#else + + ENTRY(mutex_delay_default) + push %ebp + movl %esp,%ebp + andl $-16,%esp + push %ebx + movl $93,%ebx +0: decl %ebx + jg 0b + pop %ebx + leave + ret + SET_SIZE(mutex_delay_default) + +#endif /* !__amd64 */ +#endif /* __lint */ diff --git a/usr/src/uts/intel/sys/mutex_impl.h b/usr/src/uts/intel/sys/mutex_impl.h index bcab84a979..c8cff15c2a 100644 --- a/usr/src/uts/intel/sys/mutex_impl.h +++ b/usr/src/uts/intel/sys/mutex_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -98,8 +97,31 @@ typedef union mutex_impl { #define MUTEX_DESTROY(lp) \ (lp)->m_owner = ((uintptr_t)curthread | MUTEX_DEAD) +/* mutex backoff delay macro and constants */ +#define MUTEX_BACKOFF_BASE 1 +#define MUTEX_BACKOFF_SHIFT 2 +#define MUTEX_CAP_FACTOR 64 +#define MUTEX_DELAY() { \ + mutex_delay(); \ + SMT_PAUSE(); \ + } + +/* low overhead clock read */ +#define MUTEX_GETTICK() tsc_read() +extern void null_xcall(void); +#define MUTEX_SYNC() { \ + cpuset_t set; \ + CPUSET_ALL(set); \ + xc_call(0, 0, 0, X_CALL_HIPRI, set, \ + (xc_func_t)null_xcall); \ + } extern int mutex_adaptive_tryenter(mutex_impl_t *); +extern void *mutex_owner_running(mutex_impl_t *); + +#else /* _ASM */ + +#define MUTEX_THREAD -0x8 #endif /* _ASM */ |