2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
18 * The c functions do not protect from non-interlocked accesses
19 * This is no problem as long as we do not have multiple Win32 threads
21 * The assembly macro's do protect from non-interlocked access,
22 * but they will only work for i386 systems with GCC.
25 /************************************************************************
26 * InterlockedIncrement [KERNEL32] *
28 * InterlockedIncrement adds 1 to a long variable and returns *
29 * - a negative number if the result < 0 *
30 * - zero if the result == 0 *
31 * - a positive number if the result > 0 *
33 * The returned number need not be equal to the result!!!! *
34 ************************************************************************/
36 LONG WINAPI
InterlockedIncrement(LPLONG lpAddend
)
38 #if defined(__i386__)&&defined(__GNUC__)
42 "\tlock\n" /* for SMP systems */
50 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
55 /* StopAllThreadsAndProcesses() */
60 /* ResumeAllThreadsAndProcesses() */
65 /************************************************************************
66 * InterlockedDecrement [KERNEL32] *
68 * InterlockedIncrement adds 1 to a long variable and returns *
69 * - a negative number if the result < 0 *
70 * - zero if the result == 0 *
71 * - a positive number if the result > 0 *
73 * The returned number need not be equal to the result!!!! *
74 ************************************************************************/
76 LONG WINAPI
InterlockedDecrement(LPLONG lpAddend
)
78 #if defined(__i386__)&&defined(__GNUC__)
82 "\tlock\n" /* for SMP systems */
90 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
95 /* StopAllThreadsAndProcesses() */
100 /* ResumeAllThreadsAndProcesses() */
105 /************************************************************************
106 * InterlockedExchange [KERNEL32.???]
108 * Atomically exchanges a pair of values.
111 * Prior value of value pointed to by Target
113 LONG WINAPI
InterlockedExchange(
114 LPLONG target
, /* Address of 32-bit value to exchange */
115 LONG value
/* New value for the value pointed to by target */
117 #if defined(__i386__)&&defined(__GNUC__)
119 __asm__ ( /* lock for SMP systems */
120 "lock\n\txchgl %0,(%1)"
121 :"=r" (ret
):"r" (target
), "0" (value
):"memory" );
125 /* StopAllThreadsAndProcesses() */
130 /* ResumeAllThreadsAndProcesses() */
135 /************************************************************************
136 * InterlockedCompareExchange [KERNEL32.879]
138 * Atomically compares Destination and Comperand, and if found equal exchanges
139 * the value of Destination with Exchange
142 * Prior value of value pointed to by Destination
144 PVOID WINAPI
InterlockedCompareExchange(
145 PVOID
*Destination
, /* Address of 32-bit value to exchange */
146 PVOID Exchange
, /* change value, 32 bits */
147 PVOID Comperand
/* value to compare, 32 bits */
149 #if defined(__i386__)&&defined(__GNUC__)
151 __asm__ ( /* lock for SMP systems */
155 :"r" (Destination
),"r" (Exchange
), "0" (Comperand
)
160 /* StopAllThreadsAndProcesses() */
163 if(*Destination
==Comperand
) *Destination
=Exchange
;
165 /* ResumeAllThreadsAndProcesses() */
170 /************************************************************************
171 * InterlockedExchangeAdd [KERNEL32.880]
173 * Atomically adds Increment to Addend and returns the previous value of
177 * Prior value of value pointed to by cwAddendTarget
179 LONG WINAPI
InterlockedExchangeAdd(
180 PLONG Addend
, /* Address of 32-bit value to exchange */
181 LONG Increment
/* Value to add */
183 #if defined(__i386__)&&defined(__GNUC__)
185 __asm__ ( /* lock for SMP systems */
189 :"r" (Addend
), "0" (Increment
)
194 /* StopAllThreadsAndProcesses() */
197 *Addend
+= Increment
;
199 /* ResumeAllThreadsAndProcesses() */