Merge my current work done on the kd++ branch:
[reactos.git] / reactos / include / xdk / interlocked.h
1 /******************************************************************************
2 * INTERLOCKED Functions *
3 ******************************************************************************/
4 //
5 // Intrinsics (note: taken from our winnt.h)
6 // FIXME: 64-bit
7 //
8 #if defined(__GNUC__)
9
10 static __inline__ BOOLEAN
11 InterlockedBitTestAndSet(
12 _Inout_updates_bytes_((Bit+7)/8) _Interlocked_operand_ LONG volatile *Base,
13 _In_ LONG Bit)
14 {
15 #if defined(_M_IX86)
16 LONG OldBit;
17 __asm__ __volatile__("lock "
18 "btsl %2,%1\n\t"
19 "sbbl %0,%0\n\t"
20 :"=r" (OldBit),"+m" (*Base)
21 :"Ir" (Bit)
22 : "memory");
23 return OldBit;
24 #else
25 return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;
26 #endif
27 }
28
29 static __inline__ BOOLEAN
30 InterlockedBitTestAndReset(
31 _Inout_updates_bytes_((Bit+7)/8) _Interlocked_operand_ LONG volatile *Base,
32 _In_ LONG Bit)
33 {
34 #if defined(_M_IX86)
35 LONG OldBit;
36 __asm__ __volatile__("lock "
37 "btrl %2,%1\n\t"
38 "sbbl %0,%0\n\t"
39 :"=r" (OldBit),"+m" (*Base)
40 :"Ir" (Bit)
41 : "memory");
42 return OldBit;
43 #else
44 return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;
45 #endif
46 }
47
48 #endif /* defined(__GNUC__) */
49
50 #define BitScanForward _BitScanForward
51 #define BitScanReverse _BitScanReverse
52 #define BitTest _bittest
53 #define BitTestAndComplement _bittestandcomplement
54 #define BitTestAndSet _bittestandset
55 #define BitTestAndReset _bittestandreset
56 #define InterlockedBitTestAndSet _interlockedbittestandset
57 #define InterlockedBitTestAndReset _interlockedbittestandreset
58
59 #ifdef _M_AMD64
60 #define BitScanForward64 _BitScanForward64
61 #define BitScanReverse64 _BitScanReverse64
62 #define BitTest64 _bittest64
63 #define BitTestAndComplement64 _bittestandcomplement64
64 #define BitTestAndSet64 _bittestandset64
65 #define BitTestAndReset64 _bittestandreset64
66 #define InterlockedBitTestAndSet64 _interlockedbittestandset64
67 #define InterlockedBitTestAndReset64 _interlockedbittestandreset64
68 #endif
69
70 #if !defined(__INTERLOCKED_DECLARED)
71 #define __INTERLOCKED_DECLARED
72
73 #if defined (_X86_)
74 #if defined(NO_INTERLOCKED_INTRINSICS)
75 NTKERNELAPI
76 LONG
77 FASTCALL
78 InterlockedIncrement(
79 _Inout_ _Interlocked_operand_ LONG volatile *Addend);
80
81 NTKERNELAPI
82 LONG
83 FASTCALL
84 InterlockedDecrement(
85 _Inout_ _Interlocked_operand_ LONG volatile *Addend);
86
87 NTKERNELAPI
88 LONG
89 FASTCALL
90 InterlockedCompareExchange(
91 _Inout_ _Interlocked_operand_ LONG volatile *Destination,
92 _In_ LONG Exchange,
93 _In_ LONG Comparand);
94
95 NTKERNELAPI
96 LONG
97 FASTCALL
98 InterlockedExchange(
99 _Inout_ _Interlocked_operand_ LONG volatile *Destination,
100 _In_ LONG Value);
101
102 NTKERNELAPI
103 LONG
104 FASTCALL
105 InterlockedExchangeAdd(
106 _Inout_ _Interlocked_operand_ LONG volatile *Addend,
107 _In_ LONG Value);
108
109 #else /* !defined(NO_INTERLOCKED_INTRINSICS) */
110
111 #define InterlockedExchange _InterlockedExchange
112 #define InterlockedIncrement _InterlockedIncrement
113 #define InterlockedDecrement _InterlockedDecrement
114 #define InterlockedExchangeAdd _InterlockedExchangeAdd
115 #define InterlockedCompareExchange _InterlockedCompareExchange
116 #define InterlockedOr _InterlockedOr
117 #define InterlockedAnd _InterlockedAnd
118 #define InterlockedXor _InterlockedXor
119
120 #endif /* !defined(NO_INTERLOCKED_INTRINSICS) */
121
122 #endif /* defined (_X86_) */
123
124 #if !defined (_WIN64)
125 /*
126 * PVOID
127 * InterlockedExchangePointer(
128 * IN OUT PVOID volatile *Target,
129 * IN PVOID Value)
130 */
131 #define InterlockedExchangePointer(Target, Value) \
132 ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value))
133
134 /*
135 * PVOID
136 * InterlockedCompareExchangePointer(
137 * IN OUT PVOID *Destination,
138 * IN PVOID Exchange,
139 * IN PVOID Comparand)
140 */
141 #define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \
142 ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand))
143
144 #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)
145 #define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a)
146 #define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)
147
148 #endif // !defined (_WIN64)
149
150 #if defined (_M_AMD64)
151
152 #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd64((LONGLONG *)a, (LONGLONG)b)
153 #define InterlockedIncrementSizeT(a) InterlockedIncrement64((LONGLONG *)a)
154 #define InterlockedDecrementSizeT(a) InterlockedDecrement64((LONGLONG *)a)
155 #define InterlockedAnd _InterlockedAnd
156 #define InterlockedOr _InterlockedOr
157 #define InterlockedXor _InterlockedXor
158 #define InterlockedIncrement _InterlockedIncrement
159 #define InterlockedDecrement _InterlockedDecrement
160 #define InterlockedAdd _InterlockedAdd
161 #define InterlockedExchange _InterlockedExchange
162 #define InterlockedExchangeAdd _InterlockedExchangeAdd
163 #define InterlockedCompareExchange _InterlockedCompareExchange
164 #define InterlockedAnd64 _InterlockedAnd64
165 #define InterlockedOr64 _InterlockedOr64
166 #define InterlockedXor64 _InterlockedXor64
167 #define InterlockedIncrement64 _InterlockedIncrement64
168 #define InterlockedDecrement64 _InterlockedDecrement64
169 #define InterlockedAdd64 _InterlockedAdd64
170 #define InterlockedExchange64 _InterlockedExchange64
171 #define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
172 #define InterlockedCompareExchange64 _InterlockedCompareExchange64
173 #define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
174 #define InterlockedExchangePointer _InterlockedExchangePointer
175 #define InterlockedBitTestAndSet64 _interlockedbittestandset64
176 #define InterlockedBitTestAndReset64 _interlockedbittestandreset64
177
178 #endif // _M_AMD64
179
180 #if defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS)
181 //#if !defined(_X86AMD64_) // FIXME: what's _X86AMD64_ used for?
182 FORCEINLINE
183 LONG64
184 InterlockedAdd64(
185 _Inout_ _Interlocked_operand_ LONG64 volatile *Addend,
186 _In_ LONG64 Value)
187 {
188 return InterlockedExchangeAdd64(Addend, Value) + Value;
189 }
190 //#endif
191 #endif
192
193 #endif /* !__INTERLOCKED_DECLARED */
194
195