2 * Win32 kernel functions
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1997 Onno Hovers
23 * The c functions do not protect from non-interlocked accesses
24 * This is no problem as long as we do not have multiple Win32 threads
26 * The assembly macro's do protect from non-interlocked access,
27 * but they will only work for i386 systems with GCC.
30 /************************************************************************
31 * InterlockedIncrement [KERNEL32] *
33 * InterlockedIncrement adds 1 to a long variable and returns *
34 * - a negative number if the result < 0 *
35 * - zero if the result == 0 *
36 * - a positive number if the result > 0 *
38 * The returned number need not be equal to the result!!!! *
39 ************************************************************************/
41 LONG WINAPI InterlockedIncrement(LPLONG lpAddend)
43 #if defined(__i386__)&&defined(__GNUC__)
47 "\tlock\n" /* for SMP systems */
55 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
60 /* StopAllThreadsAndProcesses() */
65 /* ResumeAllThreadsAndProcesses() */
70 /************************************************************************
71 * InterlockedDecrement [KERNEL32] *
73 * InterlockedIncrement adds 1 to a long variable and returns *
74 * - a negative number if the result < 0 *
75 * - zero if the result == 0 *
76 * - a positive number if the result > 0 *
78 * The returned number need not be equal to the result!!!! *
79 ************************************************************************/
81 LONG WINAPI InterlockedDecrement(LPLONG lpAddend)
83 #if defined(__i386__)&&defined(__GNUC__)
87 "\tlock\n" /* for SMP systems */
95 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
100 /* StopAllThreadsAndProcesses() */
105 /* ResumeAllThreadsAndProcesses() */
110 /************************************************************************
111 * InterlockedExchange [KERNEL32] *
112 ************************************************************************/
114 LONG WINAPI InterlockedExchange(LPLONG target, LONG value)
116 #if defined(__i386__)&&defined(__GNUC__)
121 "\tlock\n" /* for SMP systems */
123 :"=r" (ret):"r" (target), "0" (value):"memory"
128 /* StopAllThreadsAndProcesses() */
133 /* ResumeAllThreadsAndProcesses() */
138 /* AAARGHH some CriticalSection functions get called before we
142 #define GetCurrentThreadId() (-1)
144 /************************************************************************
145 * InitializeCriticalSection [KERNEL32] *
146 ************************************************************************/
148 void WINAPI InitializeCriticalSection(CRITICAL_SECTION *pcritical)
150 pcritical->LockCount=-1;
151 pcritical->RecursionCount=0;
152 pcritical->LockSemaphore=(HANDLE32) semget(IPC_PRIVATE,1,IPC_CREAT);
153 pcritical->OwningThread=(HANDLE32) -1;
154 pcritical->Reserved=0;
157 /************************************************************************
158 * DeleteCriticalSection [KERNEL32] *
159 ************************************************************************/
161 void WINAPI DeleteCriticalSection(CRITICAL_SECTION *pcritical)
163 semctl((int) pcritical->LockSemaphore,0,IPC_RMID,(union semun)NULL);
164 pcritical->Reserved=-1;
167 /************************************************************************
168 * EnterCriticalSection [KERNEL32] *
169 ************************************************************************/
171 void WINAPI EnterCriticalSection (CRITICAL_SECTION *pcritical)
173 if( InterlockedIncrement(&(pcritical->LockCount)))
175 if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() )
182 semop((int) pcritical->LockSemaphore,&sop,0);
184 pcritical->OwningThread = (HANDLE32) GetCurrentThreadId();
189 pcritical->OwningThread =(HANDLE32) GetCurrentThreadId();
191 pcritical->RecursionCount++;
194 /************************************************************************
195 * TryEnterCriticalSection [KERNEL32] *
196 ************************************************************************/
198 BOOL32 WINAPI TryEnterCriticalSection (CRITICAL_SECTION *pcritical)
200 if( InterlockedIncrement(&(pcritical->LockCount)))
202 if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() )
207 pcritical->OwningThread =(HANDLE32) GetCurrentThreadId();
209 pcritical->RecursionCount++;
214 /************************************************************************
215 * LeaveCriticalSection [KERNEL32] *
216 ************************************************************************/
218 void WINAPI LeaveCriticalSection(CRITICAL_SECTION *pcritical)
220 /* do we actually own this critical section ??? */
221 if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId())
224 pcritical->RecursionCount--;
225 if( pcritical->RecursionCount==0)
227 pcritical->OwningThread=(HANDLE32)-1;
228 if(InterlockedDecrement(&(pcritical->LockCount))>=0)
235 semop((int) pcritical->LockSemaphore,&sop,0);
240 InterlockedDecrement(&(pcritical->LockCount));
244 /************************************************************************
245 * ReinitializeCriticalSection [KERNEL32] *
246 ************************************************************************/
248 void WINAPI ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit)
253 /************************************************************************
254 * MakeCriticalSectionGlobal [KERNEL32] *
255 ************************************************************************/
257 void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit)
259 /* nothing (SysV Semaphores are already global) */