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) */