2 * Win32 critical sections
4 * Copyright 1998 Alexandre Julliard
10 #include <sys/types.h>
16 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(win32
);
20 DECLARE_DEBUG_CHANNEL(relay
);
22 /***********************************************************************
23 * InitializeCriticalSection (KERNEL32.@)
25 void WINAPI
InitializeCriticalSection( CRITICAL_SECTION
*crit
)
27 NTSTATUS ret
= RtlInitializeCriticalSection( crit
);
28 if (ret
) RtlRaiseStatus( ret
);
31 /***********************************************************************
32 * InitializeCriticalSectionAndSpinCount (KERNEL32.@)
34 BOOL WINAPI
InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION
*crit
, DWORD spincount
)
36 NTSTATUS ret
= RtlInitializeCriticalSectionAndSpinCount( crit
, spincount
);
37 if (ret
) RtlRaiseStatus( ret
);
41 /***********************************************************************
42 * SetCriticalSectionSpinCount (KERNEL32.@)
43 * This function is available on NT4SP3 or later, but not Win98
46 DWORD WINAPI
SetCriticalSectionSpinCount( CRITICAL_SECTION
*crit
, DWORD spincount
)
48 ULONG_PTR oldspincount
= crit
->SpinCount
;
49 if(spincount
) FIXME("critsection=%p: spincount=%ld not supported\n", crit
, spincount
);
50 crit
->SpinCount
= spincount
;
54 /***********************************************************************
55 * MakeCriticalSectionGlobal (KERNEL32.@)
57 void WINAPI
MakeCriticalSectionGlobal( CRITICAL_SECTION
*crit
)
59 /* let's assume that only one thread at a time will try to do this */
60 HANDLE sem
= crit
->LockSemaphore
;
61 if (!sem
) NtCreateSemaphore( &sem
, SEMAPHORE_ALL_ACCESS
, NULL
, 0, 1 );
62 crit
->LockSemaphore
= ConvertToGlobalHandle( sem
);
66 /***********************************************************************
67 * ReinitializeCriticalSection (KERNEL32.@)
69 void WINAPI
ReinitializeCriticalSection( CRITICAL_SECTION
*crit
)
71 if ( !crit
->LockSemaphore
)
72 RtlInitializeCriticalSection( crit
);
76 /***********************************************************************
77 * UninitializeCriticalSection (KERNEL32.@)
79 void WINAPI
UninitializeCriticalSection( CRITICAL_SECTION
*crit
)
81 RtlDeleteCriticalSection( crit
);
86 /***********************************************************************
87 * InterlockedCompareExchange (KERNEL32.@)
89 /* LONG WINAPI InterlockedCompareExchange( PLONG dest, LONG xchg, LONG compare ); */
90 __ASM_GLOBAL_FUNC(InterlockedCompareExchange
,
91 "movl 12(%esp),%eax\n\t"
92 "movl 8(%esp),%ecx\n\t"
93 "movl 4(%esp),%edx\n\t"
94 "lock; cmpxchgl %ecx,(%edx)\n\t"
97 /***********************************************************************
98 * InterlockedExchange (KERNEL32.@)
100 /* LONG WINAPI InterlockedExchange( PLONG dest, LONG val ); */
101 __ASM_GLOBAL_FUNC(InterlockedExchange
,
102 "movl 8(%esp),%eax\n\t"
103 "movl 4(%esp),%edx\n\t"
104 "lock; xchgl %eax,(%edx)\n\t"
107 /***********************************************************************
108 * InterlockedExchangeAdd (KERNEL32.@)
110 /* LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr ); */
111 __ASM_GLOBAL_FUNC(InterlockedExchangeAdd
,
112 "movl 8(%esp),%eax\n\t"
113 "movl 4(%esp),%edx\n\t"
114 "lock; xaddl %eax,(%edx)\n\t"
117 /***********************************************************************
118 * InterlockedIncrement (KERNEL32.@)
120 /* LONG WINAPI InterlockedIncrement( PLONG dest ); */
121 __ASM_GLOBAL_FUNC(InterlockedIncrement
,
122 "movl 4(%esp),%edx\n\t"
124 "lock; xaddl %eax,(%edx)\n\t"
128 /***********************************************************************
129 * InterlockedDecrement (KERNEL32.@)
131 __ASM_GLOBAL_FUNC(InterlockedDecrement
,
132 "movl 4(%esp),%edx\n\t"
134 "lock; xaddl %eax,(%edx)\n\t"
138 #elif defined(__sparc__) && defined(__sun__)
141 * As the earlier Sparc processors lack necessary atomic instructions,
142 * I'm simply falling back to the library-provided _lwp_mutex routines
143 * to ensure mutual exclusion in a way appropriate for the current
146 * FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
147 * we could use this to speed up the Interlocked operations ...
151 static lwp_mutex_t interlocked_mutex
= DEFAULTMUTEX
;
153 /***********************************************************************
154 * InterlockedCompareExchange (KERNEL32.@)
156 LONG WINAPI
InterlockedCompareExchange( PLONG dest
, LONG xchg
, LONG compare
)
158 _lwp_mutex_lock( &interlocked_mutex
);
160 if ( *dest
== compare
)
165 _lwp_mutex_unlock( &interlocked_mutex
);
169 /***********************************************************************
170 * InterlockedExchange (KERNEL32.@)
172 LONG WINAPI
InterlockedExchange( PLONG dest
, LONG val
)
175 _lwp_mutex_lock( &interlocked_mutex
);
180 _lwp_mutex_unlock( &interlocked_mutex
);
184 /***********************************************************************
185 * InterlockedExchangeAdd (KERNEL32.@)
187 LONG WINAPI
InterlockedExchangeAdd( PLONG dest
, LONG incr
)
190 _lwp_mutex_lock( &interlocked_mutex
);
195 _lwp_mutex_unlock( &interlocked_mutex
);
199 /***********************************************************************
200 * InterlockedIncrement (KERNEL32.@)
202 LONG WINAPI
InterlockedIncrement( PLONG dest
)
205 _lwp_mutex_lock( &interlocked_mutex
);
209 _lwp_mutex_unlock( &interlocked_mutex
);
213 /***********************************************************************
214 * InterlockedDecrement (KERNEL32.@)
216 LONG WINAPI
InterlockedDecrement( PLONG dest
)
219 _lwp_mutex_lock( &interlocked_mutex
);
223 _lwp_mutex_unlock( &interlocked_mutex
);
228 #error You must implement the Interlocked* functions for your CPU