Added server pid and tid in init_thread request, and use them in
[wine] / scheduler / syslevel.c
1 /*
2  * Win32 'syslevel' routines
3  *
4  * Copyright 1998 Ulrich Weigand
5  */
6
7 #include <unistd.h>
8 #include "syslevel.h"
9 #include "heap.h"
10 #include "stackframe.h"
11 #include "debug.h"
12
13 static CRITICAL_SECTION Win16Mutex;
14 static SEGPTR segpWin16Mutex;
15
16 /* Global variable to save current TEB while in 16-bit code */
17 WORD SYSLEVEL_Win16CurrentTeb = 0;
18
19 /* TEB of initial process for emergency use */
20 WORD SYSLEVEL_EmergencyTeb = 0;
21
22
23 /************************************************************************
24  *           SYSLEVEL_Init
25  */
26 void SYSLEVEL_Init(void)
27 {
28     CRITICAL_SECTION **w16Mutex = SEGPTR_ALLOC(sizeof(CRITICAL_SECTION *));
29
30     *w16Mutex = &Win16Mutex;
31     segpWin16Mutex = SEGPTR_GET(w16Mutex);
32
33     InitializeCriticalSection(&Win16Mutex);
34     MakeCriticalSectionGlobal(&Win16Mutex);
35 }
36
37 /************************************************************************
38  *           GetpWin16Lock32    (KERNEL32.93)
39  */
40 VOID WINAPI GetpWin16Lock(CRITICAL_SECTION **lock)
41 {
42     *lock = &Win16Mutex;
43 }
44
45 /************************************************************************
46  *           GetpWin16Lock16    (KERNEL.449)
47  */
48 SEGPTR WINAPI GetpWin16Lock16(void) 
49
50     return segpWin16Mutex;
51 }
52
53 /************************************************************************
54  *           _EnterSysLevel    (KERNEL32.97)
55  */
56 VOID WINAPI _EnterSysLevel(CRITICAL_SECTION *lock)
57 {
58     EnterCriticalSection(lock);
59
60     if (lock == &Win16Mutex)
61         GET_FS( SYSLEVEL_Win16CurrentTeb );
62 }
63
64 /************************************************************************
65  *           _LeaveSysLevel    (KERNEL32.98)
66  */
67 VOID WINAPI _LeaveSysLevel(CRITICAL_SECTION *lock)
68 {
69     LeaveCriticalSection(lock);
70 }
71
72 /************************************************************************
73  *           (KERNEL32.86)
74  */
75 VOID WINAPI _KERNEL32_86(CRITICAL_SECTION *lock)
76 {
77     _LeaveSysLevel(lock);
78 }
79
80 /************************************************************************
81  *           SYSLEVEL_EnterWin16Lock                    [KERNEL.480]
82  */
83 VOID WINAPI SYSLEVEL_EnterWin16Lock(VOID)
84 {
85     TRACE(win32, "thread %04x (pid %d) about to enter\n", 
86           THREAD_Current()->teb_sel, getpid());
87
88     _EnterSysLevel(&Win16Mutex);
89
90     TRACE(win32, "thread %04x (pid %d) entered, count is %ld\n",
91           THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
92 }
93
94 /************************************************************************
95  *           SYSLEVEL_LeaveWin16Lock            [KERNEL.481]
96  */
97 VOID WINAPI SYSLEVEL_LeaveWin16Lock(VOID)
98 {
99     TRACE(win32, "thread %04x (pid %d) about to leave, count is %ld\n", 
100           THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
101
102     _LeaveSysLevel(&Win16Mutex);
103 }
104
105 /************************************************************************
106  *           _CheckNotSysLevel    (KERNEL32.94)
107  */
108 VOID WINAPI _CheckNotSysLevel(CRITICAL_SECTION *lock)
109 {
110     FIXME(win32, "()\n");
111 }
112
113 /************************************************************************
114  *           _ConfirmSysLevel    (KERNEL32.95)
115  */
116 VOID WINAPI _ConfirmSysLevel(CRITICAL_SECTION *lock)
117 {
118     FIXME(win32, "()\n");
119 }
120
121 /************************************************************************
122  *           _ConfirmWin16Lock    (KERNEL32.96)
123  */
124 DWORD WINAPI _ConfirmWin16Lock(void)
125 {
126     if ( Win16Mutex.OwningThread == GetCurrentThreadId() )
127         return Win16Mutex.RecursionCount;
128     else
129         return 0L;
130 }
131
132 /************************************************************************
133  *           ReleaseThunkLock    (KERNEL32.48)
134  */
135 VOID WINAPI ReleaseThunkLock(DWORD *mutex_count)
136 {
137     DWORD count = Win16Mutex.RecursionCount;
138     *mutex_count = count;
139
140     while (count-- > 0)
141         _LeaveSysLevel(&Win16Mutex);
142 }
143
144 /************************************************************************
145  *           RestoreThunkLock    (KERNEL32.49)
146  */
147 VOID WINAPI RestoreThunkLock(DWORD mutex_count)
148 {
149     while (mutex_count-- > 0)
150         _EnterSysLevel(&Win16Mutex);
151 }
152
153 /************************************************************************
154  *           SYSLEVEL_ReleaseWin16Lock
155  */
156 VOID SYSLEVEL_ReleaseWin16Lock(VOID)
157 {
158     DWORD count;
159
160     TRACE(win32, "thread %04x (pid %d) about to release, count is %ld\n", 
161           THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
162
163     ReleaseThunkLock(&count);
164
165     if (count > 0xffff)
166         ERR(win32, "Win16Mutex recursion count too large!\n");
167
168     CURRENT_STACK16->mutex_count = (WORD)count;
169 }
170
171 /************************************************************************
172  *           SYSLEVEL_RestoreWin16Lock
173  */
174 VOID SYSLEVEL_RestoreWin16Lock(VOID)
175 {
176     DWORD count = CURRENT_STACK16->mutex_count;
177
178     if (!count)
179         ERR(win32, "Win16Mutex recursion count is zero!\n");
180
181     TRACE(win32, "thread %04x (pid %d) about to restore (count %ld)\n", 
182           THREAD_Current()->teb_sel, getpid(), count);
183
184     RestoreThunkLock(count);
185
186     TRACE(win32, "thread %04x (pid %d) restored lock, count is %ld\n", 
187           THREAD_Current()->teb_sel, getpid(), Win16Mutex.RecursionCount);
188 }
189