Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mutex_32.h
Go to the documentation of this file.
1 /*
2  * Assembly implementation of the mutex fastpath, based on atomic
3  * decrement/increment.
4  *
5  * started by Ingo Molnar:
6  *
7  * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <[email protected]>
8  */
9 #ifndef _ASM_X86_MUTEX_32_H
10 #define _ASM_X86_MUTEX_32_H
11 
12 #include <asm/alternative.h>
13 
24 #define __mutex_fastpath_lock(count, fail_fn) \
25 do { \
26  unsigned int dummy; \
27  \
28  typecheck(atomic_t *, count); \
29  typecheck_fn(void (*)(atomic_t *), fail_fn); \
30  \
31  asm volatile(LOCK_PREFIX " decl (%%eax)\n" \
32  " jns 1f \n" \
33  " call " #fail_fn "\n" \
34  "1:\n" \
35  : "=a" (dummy) \
36  : "a" (count) \
37  : "memory", "ecx", "edx"); \
38 } while (0)
39 
40 
52  int (*fail_fn)(atomic_t *))
53 {
54  if (unlikely(atomic_dec_return(count) < 0))
55  return fail_fn(count);
56  else
57  return 0;
58 }
59 
73 #define __mutex_fastpath_unlock(count, fail_fn) \
74 do { \
75  unsigned int dummy; \
76  \
77  typecheck(atomic_t *, count); \
78  typecheck_fn(void (*)(atomic_t *), fail_fn); \
79  \
80  asm volatile(LOCK_PREFIX " incl (%%eax)\n" \
81  " jg 1f\n" \
82  " call " #fail_fn "\n" \
83  "1:\n" \
84  : "=a" (dummy) \
85  : "a" (count) \
86  : "memory", "ecx", "edx"); \
87 } while (0)
88 
89 #define __mutex_slowpath_needs_to_unlock() 1
90 
103 static inline int __mutex_fastpath_trylock(atomic_t *count,
104  int (*fail_fn)(atomic_t *))
105 {
106  /*
107  * We have two variants here. The cmpxchg based one is the best one
108  * because it never induce a false contention state. It is included
109  * here because architectures using the inc/dec algorithms over the
110  * xchg ones are much more likely to support cmpxchg natively.
111  *
112  * If not we fall back to the spinlock based variant - that is
113  * just as efficient (and simpler) as a 'destructive' probing of
114  * the mutex state would be.
115  */
116 #ifdef __HAVE_ARCH_CMPXCHG
117  if (likely(atomic_cmpxchg(count, 1, 0) == 1))
118  return 1;
119  return 0;
120 #else
121  return fail_fn(count);
122 #endif
123 }
124 
125 #endif /* _ASM_X86_MUTEX_32_H */