Added support for AZERTY keyboard layout.
[wine/hacks.git] / scheduler / critsection.c
blobdabc37c4ef6c20e5c27417b42b0a40f901ef5a71
1 /*
2 * Win32 critical sections
4 * Copyright 1998 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <errno.h>
9 #include <stdio.h>
10 #include <sys/types.h>
11 #include "winerror.h"
12 #include "winbase.h"
13 #include "ntddk.h"
14 #include "heap.h"
15 #include "debugtools.h"
16 #include "thread.h"
18 DEFAULT_DEBUG_CHANNEL(win32);
19 DECLARE_DEBUG_CHANNEL(relay);
21 /***********************************************************************
22 * InitializeCriticalSection (KERNEL32.472)
24 void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit )
26 NTSTATUS ret = RtlInitializeCriticalSection( crit );
27 if (ret) RtlRaiseStatus( ret );
30 /***********************************************************************
31 * MakeCriticalSectionGlobal (KERNEL32.515)
33 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
35 /* let's assume that only one thread at a time will try to do this */
36 HANDLE sem = crit->LockSemaphore;
37 if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
38 crit->LockSemaphore = ConvertToGlobalHandle( sem );
42 /***********************************************************************
43 * ReinitializeCriticalSection (KERNEL32.581)
45 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
47 if ( !crit->LockSemaphore )
48 RtlInitializeCriticalSection( crit );
52 /***********************************************************************
53 * UninitializeCriticalSection (KERNEL32.703)
55 void WINAPI UninitializeCriticalSection( CRITICAL_SECTION *crit )
57 RtlDeleteCriticalSection( crit );
60 #ifdef __i386__
62 /***********************************************************************
63 * InterlockCompareExchange (KERNEL32.@)
65 PVOID WINAPI InterlockedCompareExchange( PVOID *dest, PVOID xchg, PVOID compare );
66 __ASM_GLOBAL_FUNC(InterlockedCompareExchange,
67 "movl 12(%esp),%eax\n\t"
68 "movl 8(%esp),%ecx\n\t"
69 "movl 4(%esp),%edx\n\t"
70 "lock; cmpxchgl %ecx,(%edx)\n\t"
71 "ret $12");
73 /***********************************************************************
74 * InterlockedExchange (KERNEL32.@)
76 LONG WINAPI InterlockedExchange( PLONG dest, LONG val );
77 __ASM_GLOBAL_FUNC(InterlockedExchange,
78 "movl 8(%esp),%eax\n\t"
79 "movl 4(%esp),%edx\n\t"
80 "lock; xchgl %eax,(%edx)\n\t"
81 "ret $8");
83 /***********************************************************************
84 * InterlockedExchangeAdd (KERNEL32.@)
86 LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr );
87 __ASM_GLOBAL_FUNC(InterlockedExchangeAdd,
88 "movl 8(%esp),%eax\n\t"
89 "movl 4(%esp),%edx\n\t"
90 "lock; xaddl %eax,(%edx)\n\t"
91 "ret $8");
93 /***********************************************************************
94 * InterlockedIncrement (KERNEL32.@)
96 LONG WINAPI InterlockedIncrement( PLONG dest );
97 __ASM_GLOBAL_FUNC(InterlockedIncrement,
98 "movl 4(%esp),%edx\n\t"
99 "movl $1,%eax\n\t"
100 "lock; xaddl %eax,(%edx)\n\t"
101 "incl %eax\n\t"
102 "ret $4");
104 /***********************************************************************
105 * InterlockDecrement (KERNEL32.@)
107 LONG WINAPI InterlockedDecrement( PLONG dest );
108 __ASM_GLOBAL_FUNC(InterlockedDecrement,
109 "movl 4(%esp),%edx\n\t"
110 "movl $-1,%eax\n\t"
111 "lock; xaddl %eax,(%edx)\n\t"
112 "decl %eax\n\t"
113 "ret $4");
115 #elif defined(__sparc__) && defined(__sun__)
118 * As the earlier Sparc processors lack necessary atomic instructions,
119 * I'm simply falling back to the library-provided _lwp_mutex routines
120 * to ensure mutual exclusion in a way appropriate for the current
121 * architecture.
123 * FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
124 * we could use this to speed up the Interlocked operations ...
127 #include <synch.h>
128 static lwp_mutex_t interlocked_mutex = DEFAULTMUTEX;
130 /***********************************************************************
131 * InterlockedCompareExchange (KERNEL32.@)
133 PVOID WINAPI InterlockedCompareExchange( PVOID *dest, PVOID xchg, PVOID compare )
135 _lwp_mutex_lock( &interlocked_mutex );
137 if ( *dest == compare )
138 *dest = xchg;
139 else
140 compare = *dest;
142 _lwp_mutex_unlock( &interlocked_mutex );
143 return compare;
146 /***********************************************************************
147 * InterlockedExchange (KERNEL32.@)
149 LONG WINAPI InterlockedExchange( PLONG dest, LONG val )
151 LONG retv;
152 _lwp_mutex_lock( &interlocked_mutex );
154 retv = *dest;
155 *dest = val;
157 _lwp_mutex_unlock( &interlocked_mutex );
158 return retv;
161 /***********************************************************************
162 * InterlockedExchangeAdd (KERNEL32.@)
164 LONG WINAPI InterlockedExchangeAdd( PLONG dest, LONG incr )
166 LONG retv;
167 _lwp_mutex_lock( &interlocked_mutex );
169 retv = *dest;
170 *dest += incr;
172 _lwp_mutex_unlock( &interlocked_mutex );
173 return retv;
176 /***********************************************************************
177 * InterlockedIncrement (KERNEL32.@)
179 LONG WINAPI InterlockedIncrement( PLONG dest )
181 LONG retv;
182 _lwp_mutex_lock( &interlocked_mutex );
184 retv = ++*dest;
186 _lwp_mutex_unlock( &interlocked_mutex );
187 return retv;
190 /***********************************************************************
191 * InterlockedDecrement (KERNEL32.@)
193 LONG WINAPI InterlockedDecrement( PLONG dest )
195 LONG retv;
196 _lwp_mutex_lock( &interlocked_mutex );
198 retv = --*dest;
200 _lwp_mutex_unlock( &interlocked_mutex );
201 return retv;
204 #else
205 #error You must implement the Interlocked* functions for your CPU
206 #endif