3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * FILE: ntoskrnl/ke/kthread.c
21 * PURPOSE: Process manager definitions
22 * PROGRAMMER: David Welch (welch@cwcom.net)
27 #ifndef __INCLUDE_INTERNAL_PS_H
28 #define __INCLUDE_INTERNAL_PS_H
31 * Defines for accessing KPCR and KTHREAD structure members
33 #define KTHREAD_INITIAL_STACK 0x18
34 #define KTHREAD_TEB 0x20
35 #define KTHREAD_KERNEL_STACK 0x28
36 #define KTHREAD_PREVIOUS_MODE 0x137
37 #define KTHREAD_TRAP_FRAME 0x128
39 #define ETHREAD_THREADS_PROCESS 0x258
41 #define KPROCESS_PAGE_TABLE_DIRECTORY 0x10
43 #define KPCR_BASE 0xFF000000
45 #define KPCR_EXCEPTION_LIST 0x0
46 #define KPCR_SELF 0x18
47 #define KPCR_CURRENT_THREAD 0x124
51 #include <internal/mm.h>
56 /* FIXME: This does not work if we have more than 24 IRQs (ie. more than one I/O APIC) */
57 #define VECTOR2IRQ(vector) (((vector) - 0x31) / 8)
58 #define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector))
61 * Processor Control Region
65 PVOID ExceptionList
; /* 00 */
66 PVOID StackBase
; /* 04 */
67 PVOID StackLimit
; /* 08 */
68 PVOID SubSystemTib
; /* 0C */
69 PVOID Reserved1
; /* 10 */
70 PVOID ArbitraryUserPointer
; /* 14 */
71 struct _KPCR
* Self
; /* 18 */
72 UCHAR ProcessorNumber
; /* 1C */
74 UCHAR Reserved2
[0x2]; /* 1E */
77 UCHAR Reserved3
[0xFC]; /* 28 */
78 struct _KTHREAD
* CurrentThread
; /* 124 */
79 } __attribute__((packed
)) KPCR
, *PKPCR
;
81 static inline PKPCR
KeGetCurrentKPCR(VOID
)
85 __asm__
__volatile__ ("movl %%fs:0x18, %0\n\t"
92 #define CURRENT_KPCR KeGetCurrentKPCR()
94 #define KeGetCurrentProcessorNumber (KeGetCurrentKPCR()->ProcessorNumber)
96 extern HANDLE SystemProcessHandle
;
98 typedef struct _KAPC_STATE
100 LIST_ENTRY ApcListHead
[2];
101 struct _KPROCESS
* Process
;
102 UCHAR KernelApcInProgress
;
103 UCHAR KernelApcPending
;
104 USHORT UserApcPending
;
105 } __attribute__((packed
)) KAPC_STATE
, *PKAPC_STATE
;
107 typedef struct _KTHREAD
109 /* For waiting on thread exit */
110 DISPATCHER_HEADER DispatcherHeader
; /* 00 */
112 /* List of mutants owned by the thread */
113 LIST_ENTRY MutantListHead
; /* 10 */
114 PVOID InitialStack
; /* 18 */
115 ULONG StackLimit
; /* 1C */
117 /* Pointer to the thread's environment block in user memory */
118 NT_TEB
* Teb
; /* 20 */
120 /* Pointer to the thread's TLS array */
121 PVOID TlsArray
; /* 24 */
122 PVOID KernelStack
; /* 28 */
123 UCHAR DebugActive
; /* 2C */
125 /* Thread state (one of THREAD_STATE_xxx constants below) */
126 UCHAR State
; /* 2D */
127 UCHAR Alerted
[2]; /* 2E */
129 UCHAR NpxState
; /* 31 */
130 UCHAR Saturation
; /* 32 */
131 CHAR Priority
; /* 33 */
132 KAPC_STATE ApcState
; /* 34 */
133 ULONG ContextSwitches
; /* 4C */
134 ULONG WaitStatus
; /* 50 */
135 KIRQL WaitIrql
; /* 54 */
136 UCHAR WaitMode
; /* 55 */
137 UCHAR WaitNext
; /* 56 */
138 UCHAR WaitReason
; /* 57 */
139 PKWAIT_BLOCK WaitBlockList
; /* 58 */
140 LIST_ENTRY WaitListEntry
; /* 5C */
141 ULONG WaitTime
; /* 64 */
142 CHAR BasePriority
; /* 68 */
143 UCHAR DecrementCount
; /* 69 */
144 UCHAR PriorityDecrement
; /* 6A */
145 UCHAR Quantum
; /* 6B */
146 KWAIT_BLOCK WaitBlock
[4]; /* 6C */
147 PVOID LegoData
; /* CC */
148 LONG KernelApcDisable
; /* D0 */
149 KAFFINITY UserAffinity
; /* D4 */
150 UCHAR SystemAffinityActive
;/* D8 */
151 UCHAR Pad
[7]; /* D9 */
152 PKQUEUE Queue
; /* E0 */
153 KSPIN_LOCK ApcQueueLock
; /* E4 */
154 KTIMER Timer
; /* E8 */
155 LIST_ENTRY QueueListEntry
; /* 110 */
156 KAFFINITY Affinity
; /* 118 */
157 UCHAR Preempted
; /* 11C */
158 UCHAR ProcessReadyQueue
; /* 11D */
159 UCHAR KernelStackResident
; /* 11E */
160 UCHAR NextProcessor
; /* 11F */
161 PVOID CallbackStack
; /* 120 */
162 BOOL Win32Thread
; /* 124 */
163 struct _KTRAP_FRAME
* TrapFrame
; /* 128 */
164 PVOID ApcStatePointer
[2]; /* 12C */
165 UCHAR EnableStackSwap
; /* 134 */
166 UCHAR LargeStack
; /* 135 */
167 UCHAR ResourceIndex
; /* 136 */
168 UCHAR PreviousMode
; /* 137 */
169 ULONG KernelTime
; /* 138 */
170 ULONG UserTime
; /* 13C */
171 KAPC_STATE SavedApcState
; /* 140 */
172 UCHAR Alertable
; /* 158 */
173 UCHAR ApcStateIndex
; /* 159 */
174 UCHAR ApcQueueable
; /* 15A */
175 UCHAR AutoAlignment
; /* 15B */
176 PVOID StackBase
; /* 15C */
177 KAPC SuspendApc
; /* 160 */
178 KSEMAPHORE SuspendSemaphore
; /* 190 */
179 LIST_ENTRY ThreadListEntry
; /* 1A4 */
180 CHAR FreezeCount
; /* 1AC */
181 UCHAR SuspendCount
; /* 1AD */
182 UCHAR IdealProcessor
; /* 1AE */
183 UCHAR DisableBoost
; /* 1AF */
186 * Below here are thread structure members that are specific to ReactOS
189 /* Added by Phillip Susi for list of threads in a process */
190 LIST_ENTRY ProcessThreadListEntry
; /* 1B0 */
192 /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */
193 KDPC TimerDpc
; /* 1B8 */
195 /* Record the last EIP value when the thread is suspended */
196 ULONG LastEip
; /* 1D8 */
197 } __attribute__((packed
)) KTHREAD
, *PKTHREAD
;
199 // According to documentation the stack should have a commited [ 1 page ] and
200 // a reserved part [ 1 M ] but can be specified otherwise in the image file.
208 // TopLevelIrp can be one of the following values:
209 // FIXME I belong somewhere else
211 #define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
212 #define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
213 #define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
214 #define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
215 #define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
217 typedef struct _TOP_LEVEL_IRP
220 ULONG TopLevelIrpConst
;
225 PACCESS_TOKEN Token
; // 0x0
226 UCHAR Unknown1
; // 0x4
227 UCHAR Unknown2
; // 0x5
229 SECURITY_IMPERSONATION_LEVEL Level
; // 0x8
230 } PS_IMPERSONATION_INFO
, *PPS_IMPERSONATION_INFO
;
232 struct _WIN32THREADDATA
;
234 typedef struct _ETHREAD
236 KTHREAD Tcb
; /* 000 */
237 TIME CreateTime
; /* 1B0/1DC */
240 TIME ExitTime
; /* 1B8/1E4 */
241 LIST_ENTRY LpcReplyChain
; /* 1B8/1E4 */
243 NTSTATUS ExitStatus
; /* 1C0/1EC */
244 LIST_ENTRY PostBlockList
; /* 1C4/1F0 */
245 LIST_ENTRY TerminationPortList
; /* 1CC/1F8 */
246 KSPIN_LOCK ActiveTimerListLock
; /* 1D4/200 */
247 LIST_ENTRY ActiveTimerListHead
; /* 1D8/204 */
248 CLIENT_ID Cid
; /* 1E0/20C */
249 KSEMAPHORE LpcReplySemaphore
; /* 1E8/214 */
250 PVOID LpcReplyMessage
; /* 1FC/228 */
251 PLARGE_INTEGER LpcReplyMessageId
; /* 200/22C */
252 ULONG PerformanceCounterLow
; /* 204/230 */
253 PPS_IMPERSONATION_INFO ImpersonationInfo
; /* 208/234 */
254 LIST_ENTRY IrpList
; /* 20C/238 */
255 TOP_LEVEL_IRP
* TopLevelIrp
; /* 214/240 */
256 PDEVICE_OBJECT DeviceToVerify
; /* 218/244 */
257 ULONG ReadClusterSize
; /* 21C/248 */
258 UCHAR ForwardClusterOnly
; /* 220/24C */
259 UCHAR DisablePageFaultClustering
; /* 221/24D */
260 UCHAR DeadThread
; /* 222/24E */
261 UCHAR HasTerminated
; /* 223/24F */
262 PVOID EventPair
; /* 224/250 */
263 ACCESS_MASK GrantedAccess
; /* 228/254 */
264 struct _EPROCESS
* ThreadsProcess
; /* 22C/258 */
265 PKSTART_ROUTINE StartAddress
; /* 230/25C */
268 LPTHREAD_START_ROUTINE Win32StartAddress
; /* 234/260 */
269 ULONG LpcReceiveMessageId
; /* 234/260 */
271 UCHAR LpcExitThreadCalled
; /* 238/264 */
272 UCHAR HardErrorsAreDisabled
; /* 239/265 */
273 UCHAR LpcReceivedMsgIdValid
; /* 23A/266 */
274 UCHAR ActiveImpersonationInfo
; /* 23B/267 */
275 ULONG PerformanceCountHigh
; /* 23C/268 */
278 * Added by David Welch (welch@cwcom.net)
280 struct _EPROCESS
* OldProcess
; /* 240/26C */
281 struct _WIN32THREADDATA
*Win32ThreadData
; // Pointer to win32 private thread data
283 } __attribute__((packed
)) ETHREAD
, *PETHREAD
;
286 typedef struct _KPROCESS
288 DISPATCHER_HEADER DispatcherHeader
; /* 000 */
289 PVOID PageTableDirectory
; /* 010 */
293 LIST_ENTRY InMemoryList
;
294 LIST_ENTRY SwappedOutList
;
298 KPRIORITY BasePriority
;
299 ULONG DefaultThreadQuantum
;
303 } KPROCESS
, *PKPROCESS
;
305 struct _WIN32PROCESSDATA
;
307 typedef struct _EPROCESS
316 ULONG UniqueProcessId
;
317 LIST_ENTRY ActiveProcessLinks
;
318 ULONG QuotaPeakPoolUsage
[2];
319 ULONG QuotaPoolUsage
[2];
322 ULONG PeakPagefileUsage
;
323 ULONG PeakVirtualUsage
;
324 LARGE_INTEGER VirtualSize
;
325 PVOID Vm
; // Actually 48 bytes
326 PVOID LastProtoPteFault
;
327 struct _EPORT
* DebugPort
;
328 struct _EPORT
* ExceptionPort
;
331 KMUTEX WorkingSetLock
;
332 PVOID WorkingSetPage
;
333 UCHAR ProcessOutswapEnabled
;
334 UCHAR ProcessOutswapped
;
335 UCHAR AddressSpaceInitialized
;
336 UCHAR AddressSpaceDeleted
;
337 KMUTEX AddressCreationLock
;
338 PVOID ForkInProgress
;
340 PKEVENT VmOperationEvent
;
341 PVOID PageDirectoryPte
;
342 LARGE_INTEGER LastFaultCount
;
346 ULONG NumberOfPrivatePages
;
347 ULONG NumberOfLockedPages
;
348 UCHAR ForkWasSuccessFul
;
349 UCHAR ExitProcessCalled
;
350 UCHAR CreateProcessReported
;
351 HANDLE SectionHandle
;
353 PVOID SectionBaseAddress
;
355 NTSTATUS LastThreadExitStatus
;
356 LARGE_INTEGER WorkingSetWatch
; //
357 ULONG InheritedFromUniqueProcessId
;
358 ACCESS_MASK GrantedAccess
;
359 ULONG DefaultHardErrorProcessing
;
360 PVOID LdtInformation
;
363 KMUTANT ProcessMutant
;
364 CHAR ImageFileName
[16];
365 LARGE_INTEGER VmTrimFaultValue
;
366 struct _WIN32PROCESSDATA
*Win32Process
;
369 * Added by David Welch (welch@mcmail.com)
371 MADDRESS_SPACE AddressSpace
;
372 HANDLE_TABLE HandleTable
;
373 LIST_ENTRY ProcessListEntry
;
376 * Added by Philip Susi for list of threads in process
378 LIST_ENTRY ThreadListHead
;
379 } EPROCESS
, *PEPROCESS
;
381 #define PROCESS_STATE_TERMINATED (1)
382 #define PROCESS_STATE_ACTIVE (2)
384 VOID
PiInitProcessManager(VOID
);
385 VOID
PiShutdownProcessManager(VOID
);
386 VOID
PsInitThreadManagment(VOID
);
387 VOID
PsInitProcessManagment(VOID
);
388 VOID
PsInitIdleThread(VOID
);
389 VOID
PsDispatchThread(ULONG NewThreadStatus
);
390 VOID
PsDispatchThreadNoLock(ULONG NewThreadStatus
);
391 VOID
PiTerminateProcessThreads(PEPROCESS Process
, NTSTATUS ExitStatus
);
392 VOID
PsTerminateOtherThread(PETHREAD Thread
, NTSTATUS ExitStatus
);
393 VOID
PsReleaseThread(PETHREAD Thread
);
394 VOID
PsBeginThread(PKSTART_ROUTINE StartRoutine
, PVOID StartContext
);
395 VOID
PsBeginThreadWithContextInternal(VOID
);
396 VOID
PiKillMostProcesses(VOID
);
397 NTSTATUS STDCALL
PiTerminateProcess(PEPROCESS Process
, NTSTATUS ExitStatus
);
398 ULONG
PsUnfreezeThread(PETHREAD Thread
, PNTSTATUS WaitStatus
);
399 ULONG
PsFreezeThread(PETHREAD Thread
, PNTSTATUS WaitStatus
,
400 UCHAR Alertable
, ULONG WaitMode
);
401 VOID
PiInitApcManagement(VOID
);
402 VOID
PiDeleteThread(PVOID ObjectBody
);
403 VOID
PiCloseThread(PVOID ObjectBody
, ULONG HandleCount
);
404 VOID
PsReapThreads(VOID
);
406 PsInitializeThread(HANDLE ProcessHandle
,
408 PHANDLE ThreadHandle
,
409 ACCESS_MASK DesiredAccess
,
410 POBJECT_ATTRIBUTES ObjectAttributes
,
413 PACCESS_TOKEN
PsReferenceEffectiveToken(PETHREAD Thread
,
414 PTOKEN_TYPE TokenType
,
416 PSECURITY_IMPERSONATION_LEVEL Level
);
418 NTSTATUS
PsOpenTokenOfProcess(HANDLE ProcessHandle
,
419 PACCESS_TOKEN
* Token
);
421 NTSTATUS
PsSuspendThread(PETHREAD Thread
, PULONG PreviousCount
);
422 NTSTATUS
PsResumeThread(PETHREAD Thread
, PULONG PreviousCount
);
425 #define THREAD_STATE_INVALID (0)
426 #define THREAD_STATE_RUNNABLE (1)
427 #define THREAD_STATE_RUNNING (2)
428 #define THREAD_STATE_SUSPENDED (3)
429 #define THREAD_STATE_FROZEN (4)
430 #define THREAD_STATE_TERMINATED_1 (5)
431 #define THREAD_STATE_TERMINATED_2 (6)
432 #define THREAD_STATE_BLOCKED (7)
433 #define THREAD_STATE_MAX (8)
437 * Internal thread priorities, added by Phillip Susi
438 * TODO: rebalence these to make use of all priorities... the ones above 16 can not all be used right now
441 #define PROCESS_PRIO_IDLE 3
442 #define PROCESS_PRIO_NORMAL 8
443 #define PROCESS_PRIO_HIGH 13
444 #define PROCESS_PRIO_RT 18
448 KeInitializeThread(PKPROCESS Process
, PKTHREAD Thread
, BOOLEAN First
);
450 VOID
HalInitFirstTask(PETHREAD thread
);
452 Ke386InitThread(PKTHREAD thread
, PKSTART_ROUTINE fn
, PVOID StartContext
);
453 VOID
HalTaskSwitch(PKTHREAD thread
);
455 Ke386InitThreadWithContext(PKTHREAD Thread
, PCONTEXT Context
);
456 NTSTATUS
HalReleaseTask(PETHREAD Thread
);
457 VOID
PiDeleteProcess(PVOID ObjectBody
);
458 VOID
PsReapThreads(VOID
);
459 VOID
PsUnfreezeOtherThread(PETHREAD Thread
);
460 VOID
PsFreezeOtherThread(PETHREAD Thread
);
461 VOID
PsFreezeProcessThreads(PEPROCESS Process
);
462 VOID
PsUnfreezeProcessThreads(PEPROCESS Process
);
463 PEPROCESS
PsGetNextProcess(PEPROCESS OldProcess
);
465 Ki386ContextSwitch(PKTHREAD NewThread
, PKTHREAD OldThread
);
467 PsBlockThread(PNTSTATUS Status
, UCHAR Alertable
, ULONG WaitMode
,
468 BOOLEAN DispatcherLock
, KIRQL WaitIrql
);
470 PsUnblockThread(PETHREAD Thread
, PNTSTATUS WaitStatus
);
472 #endif /* ASSEMBLER */
474 #endif /* __INCLUDE_INTERNAL_PS_H */