Got rid of THREAD_InitDone.
[wine/multimedia.git] / scheduler / syslevel.c
blobda715fe32bd1465e6abb47fb4d284c8243fb3b53
1 /*
2 * Win32 'syslevel' routines
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <signal.h>
10 #include "syslevel.h"
11 #include "heap.h"
12 #include "stackframe.h"
13 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(win32)
17 static SYSLEVEL Win16Mutex;
18 static SEGPTR segpWin16Mutex;
20 /* Global variable to save current TEB while in 16-bit code */
21 WORD SYSLEVEL_Win16CurrentTeb = 0;
23 /* TEB of initial process for emergency use */
24 WORD SYSLEVEL_EmergencyTeb = 0;
27 /************************************************************************
28 * SYSLEVEL_Init
30 void SYSLEVEL_Init(void)
32 SYSLEVEL **w16Mutex = SEGPTR_ALLOC(sizeof(SYSLEVEL *));
34 *w16Mutex = &Win16Mutex;
35 segpWin16Mutex = SEGPTR_GET(w16Mutex);
37 _CreateSysLevel( &Win16Mutex, 1 );
40 /************************************************************************
41 * GetpWin16Lock32 (KERNEL32.93)
43 VOID WINAPI GetpWin16Lock(SYSLEVEL **lock)
45 *lock = &Win16Mutex;
48 /************************************************************************
49 * GetpWin16Lock16 (KERNEL.449)
51 SEGPTR WINAPI GetpWin16Lock16(void)
53 return segpWin16Mutex;
56 /************************************************************************
57 * _CreateSysLevel (KERNEL.438)
59 VOID WINAPI _CreateSysLevel(SYSLEVEL *lock, INT level)
61 InitializeCriticalSection( &lock->crst );
62 MakeCriticalSectionGlobal( &lock->crst );
63 lock->level = level;
65 TRACE("(%p, %d): handle is %d\n",
66 lock, level, lock->crst.LockSemaphore );
69 /************************************************************************
70 * _EnterSysLevel (KERNEL32.97) (KERNEL.439)
72 VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
74 THDB *thdb = THREAD_Current();
75 int i;
77 TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n",
78 lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
79 thdb->sys_count[lock->level] );
81 for ( i = 3; i > lock->level; i-- )
82 if ( thdb->sys_count[i] > 0 )
84 ERR("(%p, level %d): Holding %p, level %d. Expect deadlock!\n",
85 lock, lock->level, thdb->sys_mutex[i], i );
88 EnterCriticalSection( &lock->crst );
90 thdb->sys_count[lock->level]++;
91 thdb->sys_mutex[lock->level] = lock;
93 TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n",
94 lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
95 thdb->sys_count[lock->level] );
97 if (lock == &Win16Mutex)
98 GET_FS( SYSLEVEL_Win16CurrentTeb );
101 /************************************************************************
102 * _LeaveSysLevel (KERNEL32.98) (KERNEL.440)
104 VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock)
106 THDB *thdb = THREAD_Current();
108 TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n",
109 lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
110 thdb->sys_count[lock->level] );
112 if ( thdb->sys_count[lock->level] <= 0 || thdb->sys_mutex[lock->level] != lock )
114 ERR("(%p, level %d): Invalid state: count %ld mutex %p.\n",
115 lock, lock->level, thdb->sys_count[lock->level],
116 thdb->sys_mutex[lock->level] );
118 else
120 if ( --thdb->sys_count[lock->level] == 0 )
121 thdb->sys_mutex[lock->level] = NULL;
124 LeaveCriticalSection( &lock->crst );
126 TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n",
127 lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(),
128 thdb->sys_count[lock->level] );
131 /************************************************************************
132 * (KERNEL32.86)
134 VOID WINAPI _KERNEL32_86(SYSLEVEL *lock)
136 _LeaveSysLevel(lock);
139 /************************************************************************
140 * _ConfirmSysLevel (KERNEL32.95) (KERNEL.436)
142 DWORD WINAPI _ConfirmSysLevel(SYSLEVEL *lock)
144 if ( lock && lock->crst.OwningThread == GetCurrentThreadId() )
145 return lock->crst.RecursionCount;
146 else
147 return 0L;
150 /************************************************************************
151 * _CheckNotSysLevel (KERNEL32.94) (KERNEL.437)
153 VOID WINAPI _CheckNotSysLevel(SYSLEVEL *lock)
155 FIXME("(%p)\n", lock);
159 /************************************************************************
160 * SYSLEVEL_EnterWin16Lock [KERNEL.480]
162 VOID WINAPI SYSLEVEL_EnterWin16Lock(VOID)
164 _EnterSysLevel(&Win16Mutex);
167 /************************************************************************
168 * SYSLEVEL_LeaveWin16Lock [KERNEL.481]
170 VOID WINAPI SYSLEVEL_LeaveWin16Lock(VOID)
172 _LeaveSysLevel(&Win16Mutex);
174 /************************************************************************
175 * _ConfirmWin16Lock (KERNEL32.96)
177 DWORD WINAPI _ConfirmWin16Lock(void)
179 return _ConfirmSysLevel(&Win16Mutex);
182 /************************************************************************
183 * ReleaseThunkLock (KERNEL32.48)
185 VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
187 DWORD count = _ConfirmSysLevel(&Win16Mutex);
188 *mutex_count = count;
190 while (count-- > 0)
191 _LeaveSysLevel(&Win16Mutex);
194 /************************************************************************
195 * RestoreThunkLock (KERNEL32.49)
197 VOID WINAPI RestoreThunkLock(DWORD mutex_count)
199 while (mutex_count-- > 0)
200 _EnterSysLevel(&Win16Mutex);
203 /************************************************************************
204 * SYSLEVEL_ReleaseWin16Lock
206 VOID SYSLEVEL_ReleaseWin16Lock(VOID)
208 DWORD count;
210 ReleaseThunkLock(&count);
212 if (count > 0xffff)
213 ERR("Win16Mutex recursion count too large!\n");
215 CURRENT_STACK16->mutex_count = (WORD)count;
218 /************************************************************************
219 * SYSLEVEL_RestoreWin16Lock
221 VOID SYSLEVEL_RestoreWin16Lock(VOID)
223 DWORD count = CURRENT_STACK16->mutex_count;
225 if (!count)
226 ERR("Win16Mutex recursion count is zero!\n");
228 RestoreThunkLock(count);
231 /************************************************************************
232 * SYSLEVEL_CheckNotLevel
234 VOID SYSLEVEL_CheckNotLevel( INT level )
236 THDB *thdb = THREAD_Current();
237 INT i;
239 for ( i = 3; i >= level; i-- )
240 if ( thdb->sys_count[i] > 0 )
242 ERR("(%d): Holding lock of level %d!\n",
243 level, i );
245 kill( getpid(), SIGHUP );
246 break;