Release 990815.
[wine/multimedia.git] / win32 / thread.c
blob136759725357a796079cb3fd54126e7a3539007b
1 /*
2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
6 */
8 #include <string.h>
9 #include <unistd.h>
11 #include "winbase.h"
12 #include "windef.h"
13 #include "winerror.h"
17 * FIXME:
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
20 * or processes.
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] *
27 * *
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 *
32 * *
33 * The returned number need not be equal to the result!!!! *
34 ************************************************************************/
36 LONG WINAPI InterlockedIncrement(LPLONG lpAddend)
38 #if defined(__i386__)&&defined(__GNUC__)
39 long ret;
40 __asm__
42 "\tlock\n" /* for SMP systems */
43 "\tincl (%1)\n"
44 "\tje 2f\n"
45 "\tjl 1f\n"
46 "\tincl %0\n"
47 "\tjmp 2f\n"
48 "1:\tdec %0\n"
49 "2:\n"
50 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
52 return ret;
53 #else
54 LONG ret;
55 /* StopAllThreadsAndProcesses() */
57 (*lpAddend)++;
58 ret=*lpAddend;
60 /* ResumeAllThreadsAndProcesses() */
61 return ret;
62 #endif
65 /************************************************************************
66 * InterlockedDecrement [KERNEL32] *
67 * *
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 *
72 * *
73 * The returned number need not be equal to the result!!!! *
74 ************************************************************************/
76 LONG WINAPI InterlockedDecrement(LPLONG lpAddend)
78 #if defined(__i386__)&&defined(__GNUC__)
79 LONG ret;
80 __asm__
82 "\tlock\n" /* for SMP systems */
83 "\tdecl (%1)\n"
84 "\tje 2f\n"
85 "\tjl 1f\n"
86 "\tincl %0\n"
87 "\tjmp 2f\n"
88 "1:\tdec %0\n"
89 "2:\n"
90 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
92 return ret;
93 #else
94 LONG ret;
95 /* StopAllThreadsAndProcesses() */
97 (*lpAddend)--;
98 ret=*lpAddend;
100 /* ResumeAllThreadsAndProcesses() */
101 return ret;
102 #endif
105 /************************************************************************
106 * InterlockedExchange [KERNEL32.???]
108 * Atomically exchanges a pair of values.
110 * RETURNS
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__)
118 LONG ret;
119 __asm__ ( /* lock for SMP systems */
120 "lock\n\txchgl %0,(%1)"
121 :"=r" (ret):"r" (target), "0" (value):"memory" );
122 return ret;
123 #else
124 LONG ret;
125 /* StopAllThreadsAndProcesses() */
127 ret=*target;
128 *target=value;
130 /* ResumeAllThreadsAndProcesses() */
131 return ret;
132 #endif
135 /************************************************************************
136 * InterlockedCompareExchange [KERNEL32.879]
138 * Atomically compares Destination and Comperand, and if found equal exchanges
139 * the value of Destination with Exchange
141 * RETURNS
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__)
150 PVOID ret;
151 __asm__ ( /* lock for SMP systems */
152 "lock\n\t"
153 "cmpxchgl %2,(%1)"
154 :"=r" (ret)
155 :"r" (Destination),"r" (Exchange), "0" (Comperand)
156 :"memory" );
157 return ret;
158 #else
159 PVOID ret;
160 /* StopAllThreadsAndProcesses() */
162 ret=*Destination;
163 if(*Destination==Comperand) *Destination=Exchange;
165 /* ResumeAllThreadsAndProcesses() */
166 return ret;
167 #endif
170 /************************************************************************
171 * InterlockedExchangeAdd [KERNEL32.880]
173 * Atomically adds Increment to Addend and returns the previous value of
174 * Addend
176 * RETURNS
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__)
184 LONG ret;
185 __asm__ ( /* lock for SMP systems */
186 "lock\n\t"
187 "xaddl %0,(%1)"
188 :"=r" (ret)
189 :"r" (Addend), "0" (Increment)
190 :"memory" );
191 return ret;
192 #else
193 LONG ret;
194 /* StopAllThreadsAndProcesses() */
196 ret = *Addend;
197 *Addend += Increment;
199 /* ResumeAllThreadsAndProcesses() */
200 return ret;
201 #endif