Release 980927
[wine.git] / scheduler / syslevel.c
blob483dbb05ac4d761eb992f781253fda54db4bd09a
1 /*
2 * Win32 'syslevel' routines
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <unistd.h>
8 #include "syslevel.h"
9 #include "heap.h"
10 #include "stackframe.h"
11 #include "debug.h"
13 static CRITICAL_SECTION Win16Mutex;
14 static SEGPTR segpWin16Mutex;
16 /* Global variable to save current TEB while in 16-bit code */
17 WORD SYSLEVEL_Win16CurrentTeb = 0;
20 /************************************************************************
21 * SYSLEVEL_Init
23 void SYSLEVEL_Init(void)
25 CRITICAL_SECTION **w16Mutex = SEGPTR_ALLOC(sizeof(CRITICAL_SECTION *));
27 *w16Mutex = &Win16Mutex;
28 segpWin16Mutex = SEGPTR_GET(w16Mutex);
30 InitializeCriticalSection(&Win16Mutex);
33 /************************************************************************
34 * GetpWin16Lock32 (KERNEL32.93)
36 VOID WINAPI GetpWin16Lock32(CRITICAL_SECTION **lock)
38 *lock = &Win16Mutex;
41 /************************************************************************
42 * GetpWin16Lock16 (KERNEL.449)
44 SEGPTR WINAPI GetpWin16Lock16(void)
46 return segpWin16Mutex;
49 /************************************************************************
50 * _EnterSysLevel (KERNEL32.97)
52 VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock)
54 EnterCriticalSection(lock);
56 if (lock == &Win16Mutex)
57 GET_FS( SYSLEVEL_Win16CurrentTeb );
60 /************************************************************************
61 * _LeaveSysLevel (KERNEL32.98)
63 VOID WINAPI _LeaveSysLevel(CRITICAL_SECTION *lock)
65 LeaveCriticalSection(lock);
68 /************************************************************************
69 * (KERNEL32.86)
71 VOID WINAPI _KERNEL32_86(CRITICAL_SECTION *lock)
73 _LeaveSysLevel(lock);
76 /************************************************************************
77 * SYSLEVEL_EnterWin16Lock
79 VOID SYSLEVEL_EnterWin16Lock(VOID)
81 TRACE(win32, "thread %04x (pid %d) about to enter\n",
82 THREAD_Current()->teb_sel, getpid());
84 _EnterSysLevel(&Win16Mutex);
86 TRACE(win32, "thread %04x (pid %d) entered, count is %ld\n",
87 THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
90 /************************************************************************
91 * SYSLEVEL_LeaveWin16Lock
93 VOID SYSLEVEL_LeaveWin16Lock(VOID)
95 TRACE(win32, "thread %04x (pid %d) about to leave, count is %ld\n",
96 THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
98 _LeaveSysLevel(&Win16Mutex);
101 /************************************************************************
102 * _CheckNotSysLevel (KERNEL32.94)
104 VOID WINAPI _CheckNotSysLevel(CRITICAL_SECTION *lock)
106 FIXME(win32, "()\n");
109 /************************************************************************
110 * _ConfirmSysLevel (KERNEL32.95)
112 VOID WINAPI _ConfirmSysLevel(CRITICAL_SECTION *lock)
114 FIXME(win32, "()\n");
117 /************************************************************************
118 * _ConfirmWin16Lock (KERNEL32.96)
120 DWORD WINAPI _ConfirmWin16Lock(void)
122 FIXME(win32, "()\n");
123 return 1;
126 /************************************************************************
127 * ReleaseThunkLock (KERNEL32.48)
129 VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
131 DWORD count = Win16Mutex.RecursionCount;
132 *mutex_count = count;
134 while (count-- > 0)
135 _LeaveSysLevel(&Win16Mutex);
138 /************************************************************************
139 * RestoreThunkLock (KERNEL32.49)
141 VOID WINAPI RestoreThunkLock(DWORD mutex_count)
143 while (mutex_count-- > 0)
144 _EnterSysLevel(&Win16Mutex);
147 /************************************************************************
148 * SYSLEVEL_ReleaseWin16Lock
150 VOID SYSLEVEL_ReleaseWin16Lock(VOID)
152 DWORD count;
154 TRACE(win32, "thread %04x (pid %d) about to release, count is %ld\n",
155 THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
157 ReleaseThunkLock(&count);
159 if (count > 0xffff)
160 ERR(win32, "Win16Mutex recursion count too large!\n");
162 CURRENT_STACK16->mutex_count = (WORD)count;
165 /************************************************************************
166 * SYSLEVEL_RestoreWin16Lock
168 VOID SYSLEVEL_RestoreWin16Lock(VOID)
170 DWORD count = CURRENT_STACK16->mutex_count;
172 if (!count)
173 ERR(win32, "Win16Mutex recursion count is zero!\n");
175 TRACE(win32, "thread %04x (pid %d) about to restore (count %ld)\n",
176 THREAD_Current()->teb_sel, getpid(), count);
178 RestoreThunkLock(count);
180 TRACE(win32, "thread %04x (pid %d) restored lock, count is %ld\n",
181 THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);