Got rid of THREAD_InitDone.
[wine/multimedia.git] / win32 / thread.c
blobc0b489ddbcd91b0154216144f042ec33c0b1e61c
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"
15 * FIXME:
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
18 * or processes.
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] *
25 * *
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 *
30 * *
31 * The returned number need not be equal to the result!!!! *
32 ************************************************************************/
34 LONG WINAPI InterlockedIncrement(LPLONG lpAddend)
36 #if defined(__i386__)&&defined(__GNUC__)
37 long ret;
38 __asm__
40 "\tlock\n" /* for SMP systems */
41 "\tincl (%1)\n"
42 "\tje 2f\n"
43 "\tjl 1f\n"
44 "\tincl %0\n"
45 "\tjmp 2f\n"
46 "1:\tdec %0\n"
47 "2:\n"
48 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
50 return ret;
51 #else
52 LONG ret;
53 /* StopAllThreadsAndProcesses() */
55 (*lpAddend)++;
56 ret=*lpAddend;
58 /* ResumeAllThreadsAndProcesses() */
59 return ret;
60 #endif
63 /************************************************************************
64 * InterlockedDecrement [KERNEL32] *
65 * *
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 *
70 * *
71 * The returned number need not be equal to the result!!!! *
72 ************************************************************************/
74 LONG WINAPI InterlockedDecrement(LPLONG lpAddend)
76 #if defined(__i386__)&&defined(__GNUC__)
77 LONG ret;
78 __asm__
80 "\tlock\n" /* for SMP systems */
81 "\tdecl (%1)\n"
82 "\tje 2f\n"
83 "\tjl 1f\n"
84 "\tincl %0\n"
85 "\tjmp 2f\n"
86 "1:\tdec %0\n"
87 "2:\n"
88 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
90 return ret;
91 #else
92 LONG ret;
93 /* StopAllThreadsAndProcesses() */
95 (*lpAddend)--;
96 ret=*lpAddend;
98 /* ResumeAllThreadsAndProcesses() */
99 return ret;
100 #endif
103 /************************************************************************
104 * InterlockedExchange [KERNEL32.???]
106 * Atomically exchanges a pair of values.
108 * RETURNS
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__)
116 LONG ret;
117 __asm__ ( /* lock for SMP systems */
118 "lock\n\txchgl %0,(%1)"
119 :"=r" (ret):"r" (target), "0" (value):"memory" );
120 return ret;
121 #else
122 LONG ret;
123 /* StopAllThreadsAndProcesses() */
125 ret=*target;
126 *target=value;
128 /* ResumeAllThreadsAndProcesses() */
129 return ret;
130 #endif
133 /************************************************************************
134 * InterlockedCompareExchange [KERNEL32.879]
136 * Atomically compares Destination and Comperand, and if found equal exchanges
137 * the value of Destination with Exchange
139 * RETURNS
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__)
148 PVOID ret;
149 __asm__ ( /* lock for SMP systems */
150 "lock\n\t"
151 "cmpxchgl %2,(%1)"
152 :"=r" (ret)
153 :"r" (Destination),"r" (Exchange), "0" (Comperand)
154 :"memory" );
155 return ret;
156 #else
157 PVOID ret;
158 /* StopAllThreadsAndProcesses() */
160 ret=*Destination;
161 if(*Destination==Comperand) *Destination=Exchange;
163 /* ResumeAllThreadsAndProcesses() */
164 return ret;
165 #endif
168 /************************************************************************
169 * InterlockedExchangeAdd [KERNEL32.880]
171 * Atomically adds Increment to Addend and returns the previous value of
172 * Addend
174 * RETURNS
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__)
182 LONG ret;
183 __asm__ ( /* lock for SMP systems */
184 "lock\n\t"
185 "xaddl %0,(%1)"
186 :"=r" (ret)
187 :"r" (Addend), "0" (Increment)
188 :"memory" );
189 return ret;
190 #else
191 LONG ret;
192 /* StopAllThreadsAndProcesses() */
194 ret = *Addend;
195 *Addend += Increment;
197 /* ResumeAllThreadsAndProcesses() */
198 return ret;
199 #endif