2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
16 * The c functions do not protect from non-interlocked accesses
17 * This is no problem as long as we do not have multiple Win32 threads
19 * The assembly macro's do protect from non-interlocked access,
20 * but they will only work for i386 systems with GCC.
23 /************************************************************************
24 * InterlockedIncrement [KERNEL32] *
26 * InterlockedIncrement adds 1 to a long variable and returns *
27 * - a negative number if the result < 0 *
28 * - zero if the result == 0 *
29 * - a positive number if the result > 0 *
31 * The returned number need not be equal to the result!!!! *
32 ************************************************************************/
34 LONG WINAPI
InterlockedIncrement(LPLONG lpAddend
)
36 #if defined(__i386__)&&defined(__GNUC__)
40 "\tlock\n" /* for SMP systems */
48 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
53 /* StopAllThreadsAndProcesses() */
58 /* ResumeAllThreadsAndProcesses() */
63 /************************************************************************
64 * InterlockedDecrement [KERNEL32] *
66 * InterlockedIncrement adds 1 to a long variable and returns *
67 * - a negative number if the result < 0 *
68 * - zero if the result == 0 *
69 * - a positive number if the result > 0 *
71 * The returned number need not be equal to the result!!!! *
72 ************************************************************************/
74 LONG WINAPI
InterlockedDecrement(LPLONG lpAddend
)
76 #if defined(__i386__)&&defined(__GNUC__)
80 "\tlock\n" /* for SMP systems */
88 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
93 /* StopAllThreadsAndProcesses() */
98 /* ResumeAllThreadsAndProcesses() */
103 /************************************************************************
104 * InterlockedExchange [KERNEL32.???]
106 * Atomically exchanges a pair of values.
109 * Prior value of value pointed to by Target
111 LONG WINAPI
InterlockedExchange(
112 LPLONG target
, /* Address of 32-bit value to exchange */
113 LONG value
/* New value for the value pointed to by target */
115 #if defined(__i386__)&&defined(__GNUC__)
117 __asm__ ( /* lock for SMP systems */
118 "lock\n\txchgl %0,(%1)"
119 :"=r" (ret
):"r" (target
), "0" (value
):"memory" );
123 /* StopAllThreadsAndProcesses() */
128 /* ResumeAllThreadsAndProcesses() */
133 /************************************************************************
134 * InterlockedCompareExchange [KERNEL32.879]
136 * Atomically compares Destination and Comperand, and if found equal exchanges
137 * the value of Destination with Exchange
140 * Prior value of value pointed to by Destination
142 PVOID WINAPI
InterlockedCompareExchange(
143 PVOID
*Destination
, /* Address of 32-bit value to exchange */
144 PVOID Exchange
, /* change value, 32 bits */
145 PVOID Comperand
/* value to compare, 32 bits */
147 #if defined(__i386__)&&defined(__GNUC__)
149 __asm__ ( /* lock for SMP systems */
153 :"r" (Destination
),"r" (Exchange
), "0" (Comperand
)
158 /* StopAllThreadsAndProcesses() */
161 if(*Destination
==Comperand
) *Destination
=Exchange
;
163 /* ResumeAllThreadsAndProcesses() */
168 /************************************************************************
169 * InterlockedExchangeAdd [KERNEL32.880]
171 * Atomically adds Increment to Addend and returns the previous value of
175 * Prior value of value pointed to by cwAddendTarget
177 LONG WINAPI
InterlockedExchangeAdd(
178 PLONG Addend
, /* Address of 32-bit value to exchange */
179 LONG Increment
/* Value to add */
181 #if defined(__i386__)&&defined(__GNUC__)
183 __asm__ ( /* lock for SMP systems */
187 :"r" (Addend
), "0" (Increment
)
192 /* StopAllThreadsAndProcesses() */
195 *Addend
+= Increment
;
197 /* ResumeAllThreadsAndProcesses() */