Define environment variable TMP as an alias for TEMP.
[wine/multimedia.git] / scheduler / syslevel.c
blob4de5e79e710b50bd35d077a7dddfa8c0dbf38346
1 /*
2 * Win32 'syslevel' routines
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include "ntddk.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 = { CRITICAL_SECTION_INIT, 1 };
19 /* Global variable to save current TEB while in 16-bit code */
20 WORD SYSLEVEL_Win16CurrentTeb = 0;
23 /************************************************************************
24 * GetpWin16Lock (KERNEL32.93)
26 VOID WINAPI GetpWin16Lock(SYSLEVEL **lock)
28 *lock = &Win16Mutex;
31 /************************************************************************
32 * GetpWin16Lock16 (KERNEL.449)
34 SEGPTR WINAPI GetpWin16Lock16(void)
36 static SEGPTR segpWin16Mutex;
37 if (!segpWin16Mutex)
39 SYSLEVEL **w16Mutex = SEGPTR_ALLOC(sizeof(SYSLEVEL *));
40 *w16Mutex = &Win16Mutex;
41 segpWin16Mutex = SEGPTR_GET(w16Mutex);
43 return segpWin16Mutex;
46 /************************************************************************
47 * _CreateSysLevel (KERNEL.438)
49 VOID WINAPI _CreateSysLevel(SYSLEVEL *lock, INT level)
51 InitializeCriticalSection( &lock->crst );
52 lock->level = level;
54 TRACE("(%p, %d): handle is %d\n",
55 lock, level, lock->crst.LockSemaphore );
58 /************************************************************************
59 * _EnterSysLevel (KERNEL32.97) (KERNEL.439)
61 VOID WINAPI _EnterSysLevel(SYSLEVEL *lock)
63 TEB *teb = NtCurrentTeb();
64 int i;
66 TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count before %ld\n",
67 lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
68 teb->sys_count[lock->level] );
70 for ( i = 3; i > lock->level; i-- )
71 if ( teb->sys_count[i] > 0 )
73 ERR("(%p, level %d): Holding %p, level %d. Expect deadlock!\n",
74 lock, lock->level, teb->sys_mutex[i], i );
77 EnterCriticalSection( &lock->crst );
79 teb->sys_count[lock->level]++;
80 teb->sys_mutex[lock->level] = lock;
82 TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count after %ld\n",
83 lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
84 teb->sys_count[lock->level] );
86 if (lock == &Win16Mutex)
87 SYSLEVEL_Win16CurrentTeb = __get_fs();
90 /************************************************************************
91 * _LeaveSysLevel (KERNEL32.98) (KERNEL.440)
93 VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock)
95 TEB *teb = NtCurrentTeb();
97 TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count before %ld\n",
98 lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
99 teb->sys_count[lock->level] );
101 if ( teb->sys_count[lock->level] <= 0 || teb->sys_mutex[lock->level] != lock )
103 ERR("(%p, level %d): Invalid state: count %ld mutex %p.\n",
104 lock, lock->level, teb->sys_count[lock->level],
105 teb->sys_mutex[lock->level] );
107 else
109 if ( --teb->sys_count[lock->level] == 0 )
110 teb->sys_mutex[lock->level] = NULL;
113 LeaveCriticalSection( &lock->crst );
115 TRACE("(%p, level %d): thread %p (fs %04x, pid %ld) count after %ld\n",
116 lock, lock->level, teb->tid, teb->teb_sel, (long) getpid(),
117 teb->sys_count[lock->level] );
120 /************************************************************************
121 * _KERNEL32_86 (KERNEL32.86)
123 VOID WINAPI _KERNEL32_86(SYSLEVEL *lock)
125 _LeaveSysLevel(lock);
128 /************************************************************************
129 * _ConfirmSysLevel (KERNEL32.95) (KERNEL.436)
131 DWORD WINAPI _ConfirmSysLevel(SYSLEVEL *lock)
133 if ( lock && lock->crst.OwningThread == GetCurrentThreadId() )
134 return lock->crst.RecursionCount;
135 else
136 return 0L;
139 /************************************************************************
140 * _CheckNotSysLevel (KERNEL32.94) (KERNEL.437)
142 VOID WINAPI _CheckNotSysLevel(SYSLEVEL *lock)
144 FIXME("(%p)\n", lock);
148 /************************************************************************
149 * _EnterWin16Lock [KERNEL.480]
151 VOID WINAPI _EnterWin16Lock(void)
153 _EnterSysLevel(&Win16Mutex);
156 /************************************************************************
157 * _LeaveWin16Lock [KERNEL.481]
159 VOID WINAPI _LeaveWin16Lock(void)
161 _LeaveSysLevel(&Win16Mutex);
164 /************************************************************************
165 * _ConfirmWin16Lock (KERNEL32.96)
167 DWORD WINAPI _ConfirmWin16Lock(void)
169 return _ConfirmSysLevel(&Win16Mutex);
172 /************************************************************************
173 * ReleaseThunkLock (KERNEL32.48)
175 VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
177 DWORD count = _ConfirmSysLevel(&Win16Mutex);
178 *mutex_count = count;
180 while (count-- > 0)
181 _LeaveSysLevel(&Win16Mutex);
184 /************************************************************************
185 * RestoreThunkLock (KERNEL32.49)
187 VOID WINAPI RestoreThunkLock(DWORD mutex_count)
189 while (mutex_count-- > 0)
190 _EnterSysLevel(&Win16Mutex);
193 /************************************************************************
194 * SYSLEVEL_CheckNotLevel
196 VOID SYSLEVEL_CheckNotLevel( INT level )
198 INT i;
200 for ( i = 3; i >= level; i-- )
201 if ( NtCurrentTeb()->sys_count[i] > 0 )
203 ERR("(%d): Holding lock of level %d!\n",
204 level, i );
205 DbgBreakPoint();
206 break;