mutex subsystem, add include/asm-x86_64/mutex.h
PATCH 4/11 mutex subsystem, add include/asm-x86_64/mutex.h
add the x86_64 version of mutex.h, optimized in assembly.
Signed-off-by Ingo Molnar <[email protected]>
Signed-off-by Arjan van de Ven <[email protected]>
----
include/asm-x86_64/mutex.h | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+)
include/asm-x86_64/mutex.h new file +74 -0
@@ -0,0 +1,74 @@ +/* +* Assembly implementation of the mutex fastpath, based on atomic +* decrement/increment. +* +* started by Ingo Molnar: +* +* Copyright (C) 2004, 2005 Red Hat, Inc., Ingo Molnar <[email protected]> +*/ +#ifndef _ASM_MUTEX_H +#define _ASM_MUTEX_H + +/** +* __mutex_fastpath_lock - decrement and call function if negative +* @v: pointer of type atomic_t +* @fn: function to call if the result is negative +* +* Atomically decrements @v and calls <fn> if the result is negative. +*/ +#define __mutex_fastpath_lock(v, fn_name) \ +do { \ + /* type-check the function too: */ \ + fastcall void (*__tmp)(atomic_t *) = fn_name; \ + unsigned long dummy; \ + \ + (void)__tmp; \ + typecheck(atomic_t *, v); \ + \ + __asm__ __volatile__( \ + LOCK "decl (%%rdi)\n" \ + "js 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2: call "#fn_name"\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=D" (dummy) \ + :"D" (v) \ + :"rax", "rsi", "rdx", "rcx", \ + "r8", "r9", "r10", "r11", "memory"); \ +} while (0) + +/** +* __mutex_fastpath_unlock - increment and call function if nonpositive +* @v: pointer of type atomic_t +* @fn: function to call if the result is nonpositive +* +* Atomically increments @v and calls <fn> if the result is nonpositive. +*/ +#define __mutex_fastpath_unlock(v, fn_name) \ +do { \ + /* type-check the function too: */ \ + fastcall void (*__tmp)(atomic_t *) = fn_name; \ + unsigned long dummy; \ + \ + (void)__tmp; \ + typecheck(atomic_t *, v); \ + \ + __asm__ __volatile__( \ + LOCK "incl (%%rdi)\n" \ + "jle 2f\n" \ + "1:\n" \ + LOCK_SECTION_START("") \ + "2: call "#fn_name"\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END \ + :"=D" (dummy) \ + :"D" (v) \ + :"rax", "rsi", "rdx", "rcx", \ + "r8", "r9", "r10", "r11", "memory"); \ +} while (0) + +#define __mutex_slowpath_needs_to_unlock () 1 + +#endif