Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sync_bitops.h
Go to the documentation of this file.
1 #ifndef _ASM_X86_SYNC_BITOPS_H
2 #define _ASM_X86_SYNC_BITOPS_H
3 
4 /*
5  * Copyright 1992, Linus Torvalds.
6  */
7 
8 /*
9  * These have to be done with inline assembly: that way the bit-setting
10  * is guaranteed to be atomic. All bit operations return 0 if the bit
11  * was cleared before the operation and != 0 if it was not.
12  *
13  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
14  */
15 
16 #define ADDR (*(volatile long *)addr)
17 
29 static inline void sync_set_bit(int nr, volatile unsigned long *addr)
30 {
31  asm volatile("lock; btsl %1,%0"
32  : "+m" (ADDR)
33  : "Ir" (nr)
34  : "memory");
35 }
36 
47 static inline void sync_clear_bit(int nr, volatile unsigned long *addr)
48 {
49  asm volatile("lock; btrl %1,%0"
50  : "+m" (ADDR)
51  : "Ir" (nr)
52  : "memory");
53 }
54 
64 static inline void sync_change_bit(int nr, volatile unsigned long *addr)
65 {
66  asm volatile("lock; btcl %1,%0"
67  : "+m" (ADDR)
68  : "Ir" (nr)
69  : "memory");
70 }
71 
80 static inline int sync_test_and_set_bit(int nr, volatile unsigned long *addr)
81 {
82  int oldbit;
83 
84  asm volatile("lock; btsl %2,%1\n\tsbbl %0,%0"
85  : "=r" (oldbit), "+m" (ADDR)
86  : "Ir" (nr) : "memory");
87  return oldbit;
88 }
89 
98 static inline int sync_test_and_clear_bit(int nr, volatile unsigned long *addr)
99 {
100  int oldbit;
101 
102  asm volatile("lock; btrl %2,%1\n\tsbbl %0,%0"
103  : "=r" (oldbit), "+m" (ADDR)
104  : "Ir" (nr) : "memory");
105  return oldbit;
106 }
107 
116 static inline int sync_test_and_change_bit(int nr, volatile unsigned long *addr)
117 {
118  int oldbit;
119 
120  asm volatile("lock; btcl %2,%1\n\tsbbl %0,%0"
121  : "=r" (oldbit), "+m" (ADDR)
122  : "Ir" (nr) : "memory");
123  return oldbit;
124 }
125 
126 #define sync_test_bit(nr, addr) test_bit(nr, addr)
127 
128 #undef ADDR
129 
130 #endif /* _ASM_X86_SYNC_BITOPS_H */