Removed all implementation aspects.
[wine.git] / win32 / thread.c
blob04efba5d9e3ddcba4b008e67d5a15112d023ad10
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
6 */
8 #include <unistd.h>
9 #include <string.h>
10 #include "windef.h"
11 #include "winerror.h"
12 #include "debug.h"
16 * FIXME:
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
19 * or processes.
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] *
26 * *
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 *
31 * *
32 * The returned number need not be equal to the result!!!! *
33 ************************************************************************/
35 LONG WINAPI InterlockedIncrement(LPLONG lpAddend)
37 #if defined(__i386__)&&defined(__GNUC__)
38 long ret;
39 __asm__
41 "\tlock\n" /* for SMP systems */
42 "\tincl (%1)\n"
43 "\tje 2f\n"
44 "\tjl 1f\n"
45 "\tincl %0\n"
46 "\tjmp 2f\n"
47 "1:\tdec %0\n"
48 "2:\n"
49 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
51 return ret;
52 #else
53 LONG ret;
54 /* StopAllThreadsAndProcesses() */
56 (*lpAddend)++;
57 ret=*lpAddend;
59 /* ResumeAllThreadsAndProcesses() */
60 return ret;
61 #endif
64 /************************************************************************
65 * InterlockedDecrement [KERNEL32] *
66 * *
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 *
71 * *
72 * The returned number need not be equal to the result!!!! *
73 ************************************************************************/
75 LONG WINAPI InterlockedDecrement(LPLONG lpAddend)
77 #if defined(__i386__)&&defined(__GNUC__)
78 LONG ret;
79 __asm__
81 "\tlock\n" /* for SMP systems */
82 "\tdecl (%1)\n"
83 "\tje 2f\n"
84 "\tjl 1f\n"
85 "\tincl %0\n"
86 "\tjmp 2f\n"
87 "1:\tdec %0\n"
88 "2:\n"
89 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
91 return ret;
92 #else
93 LONG ret;
94 /* StopAllThreadsAndProcesses() */
96 (*lpAddend)--;
97 ret=*lpAddend;
99 /* ResumeAllThreadsAndProcesses() */
100 return ret;
101 #endif
104 /************************************************************************
105 * InterlockedExchange [KERNEL32.???]
107 * Atomically exchanges a pair of values.
109 * RETURNS
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__)
117 LONG ret;
118 __asm__ ( /* lock for SMP systems */
119 "lock\n\txchgl %0,(%1)"
120 :"=r" (ret):"r" (target), "0" (value):"memory" );
121 return ret;
122 #else
123 LONG ret;
124 /* StopAllThreadsAndProcesses() */
126 ret=*target;
127 *target=value;
129 /* ResumeAllThreadsAndProcesses() */
130 return ret;
131 #endif
134 /************************************************************************
135 * InterlockedCompareExchange [KERNEL32.879]
137 * Atomically compares Destination and Comperand, and if found equal exchanges
138 * the value of Destination with Exchange
140 * RETURNS
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__)
149 PVOID ret;
150 __asm__ ( /* lock for SMP systems */
151 "lock\n\t"
152 "cmpxchgl %2,(%1)"
153 :"=r" (ret)
154 :"r" (Destination),"r" (Exchange), "0" (Comperand)
155 :"memory" );
156 return ret;
157 #else
158 PVOID ret;
159 /* StopAllThreadsAndProcesses() */
161 ret=*Destination;
162 if(*Destination==Comperand) *Destination=Exchange;
164 /* ResumeAllThreadsAndProcesses() */
165 return ret;
166 #endif
169 /************************************************************************
170 * InterlockedExchangeAdd [KERNEL32.880]
172 * Atomically adds Increment to Addend and returns the previous value of
173 * Addend
175 * RETURNS
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__)
183 LONG ret;
184 __asm__ ( /* lock for SMP systems */
185 "lock\n\t"
186 "xaddl %0,(%1)"
187 :"=r" (ret)
188 :"r" (Addend), "0" (Increment)
189 :"memory" );
190 return ret;
191 #else
192 LONG ret;
193 /* StopAllThreadsAndProcesses() */
195 ret = *Addend;
196 *Addend += Increment;
198 /* ResumeAllThreadsAndProcesses() */
199 return ret;
200 #endif