2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
17 * The c functions do not protect from non-interlocked accesses
18 * This is no problem as long as we do not have multiple Win32 threads
20 * The assembly macro's do protect from non-interlocked access,
21 * but they will only work for i386 systems with GCC.
24 /************************************************************************
25 * InterlockedIncrement [KERNEL32] *
27 * InterlockedIncrement adds 1 to a long variable and returns *
28 * - a negative number if the result < 0 *
29 * - zero if the result == 0 *
30 * - a positive number if the result > 0 *
32 * The returned number need not be equal to the result!!!! *
33 ************************************************************************/
35 LONG WINAPI
InterlockedIncrement(LPLONG lpAddend
)
37 #if defined(__i386__)&&defined(__GNUC__)
41 "\tlock\n" /* for SMP systems */
49 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
54 /* StopAllThreadsAndProcesses() */
59 /* ResumeAllThreadsAndProcesses() */
64 /************************************************************************
65 * InterlockedDecrement [KERNEL32] *
67 * InterlockedIncrement adds 1 to a long variable and returns *
68 * - a negative number if the result < 0 *
69 * - zero if the result == 0 *
70 * - a positive number if the result > 0 *
72 * The returned number need not be equal to the result!!!! *
73 ************************************************************************/
75 LONG WINAPI
InterlockedDecrement(LPLONG lpAddend
)
77 #if defined(__i386__)&&defined(__GNUC__)
81 "\tlock\n" /* for SMP systems */
89 :"=r" (ret
):"r" (lpAddend
), "0" (0): "memory"
94 /* StopAllThreadsAndProcesses() */
99 /* ResumeAllThreadsAndProcesses() */
104 /************************************************************************
105 * InterlockedExchange [KERNEL32.???]
107 * Atomically exchanges a pair of values.
110 * Prior value of value pointed to by Target
112 LONG WINAPI
InterlockedExchange(
113 LPLONG target
, /* Address of 32-bit value to exchange */
114 LONG value
/* New value for the value pointed to by target */
116 #if defined(__i386__)&&defined(__GNUC__)
118 __asm__ ( /* lock for SMP systems */
119 "lock\n\txchgl %0,(%1)"
120 :"=r" (ret
):"r" (target
), "0" (value
):"memory" );
124 /* StopAllThreadsAndProcesses() */
129 /* ResumeAllThreadsAndProcesses() */
134 /************************************************************************
135 * InterlockedCompareExchange [KERNEL32.879]
137 * Atomically compares Destination and Comperand, and if found equal exchanges
138 * the value of Destination with Exchange
141 * Prior value of value pointed to by Destination
143 PVOID WINAPI
InterlockedCompareExchange(
144 PVOID
*Destination
, /* Address of 32-bit value to exchange */
145 PVOID Exchange
, /* change value, 32 bits */
146 PVOID Comperand
/* value to compare, 32 bits */
148 #if defined(__i386__)&&defined(__GNUC__)
150 __asm__ ( /* lock for SMP systems */
154 :"r" (Destination
),"r" (Exchange
), "0" (Comperand
)
159 /* StopAllThreadsAndProcesses() */
162 if(*Destination
==Comperand
) *Destination
=Exchange
;
164 /* ResumeAllThreadsAndProcesses() */
169 /************************************************************************
170 * InterlockedExchangeAdd [KERNEL32.880]
172 * Atomically adds Increment to Addend and returns the previous value of
176 * Prior value of value pointed to by cwAddendTarget
178 LONG WINAPI
InterlockedExchangeAdd(
179 PLONG Addend
, /* Address of 32-bit value to exchange */
180 LONG Increment
/* Value to add */
182 #if defined(__i386__)&&defined(__GNUC__)
184 __asm__ ( /* lock for SMP systems */
188 :"r" (Addend
), "0" (Increment
)
193 /* StopAllThreadsAndProcesses() */
196 *Addend
+= Increment
;
198 /* ResumeAllThreadsAndProcesses() */