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.
21 * FILE: ntoskrnl/ke/kthread.c
22 * PURPOSE: Process manager definitions
23 * PROGRAMMER: David Welch (welch@cwcom.net)
28 #ifndef __INCLUDE_INTERNAL_PS_H
29 #define __INCLUDE_INTERNAL_PS_H
33 /* Forward declarations. */
39 #include <internal/arch/ps.h>
43 #include <internal/mm.h>
47 #define KeGetCurrentProcessorNumber() (KeGetCurrentKPCR()->ProcessorNumber)
50 extern HANDLE SystemProcessHandle;
52 extern LCID PsDefaultThreadLocaleId;
53 extern LCID PsDefaultSystemLocaleId;
57 typedef struct _KAPC_STATE
59 LIST_ENTRY ApcListHead[2];
60 struct _KPROCESS* Process;
61 UCHAR KernelApcInProgress;
62 UCHAR KernelApcPending;
63 USHORT UserApcPending;
64 } __attribute__((packed)) KAPC_STATE, *PKAPC_STATE;
66 #endif /* __USE_W32API */
68 typedef struct _KTHREAD
70 /* For waiting on thread exit */
71 DISPATCHER_HEADER DispatcherHeader; /* 00 */
73 /* List of mutants owned by the thread */
74 LIST_ENTRY MutantListHead; /* 10 */
75 PVOID InitialStack; /* 18 */
76 ULONG StackLimit; /* 1C */
78 /* Pointer to the thread's environment block in user memory */
81 /* Pointer to the thread's TLS array */
82 PVOID TlsArray; /* 24 */
83 PVOID KernelStack; /* 28 */
84 UCHAR DebugActive; /* 2C */
86 /* Thread state (one of THREAD_STATE_xxx constants below) */
88 UCHAR Alerted[2]; /* 2E */
90 UCHAR NpxState; /* 31 */
91 UCHAR Saturation; /* 32 */
92 CHAR Priority; /* 33 */
93 KAPC_STATE ApcState; /* 34 */
94 ULONG ContextSwitches; /* 4C */
95 ULONG WaitStatus; /* 50 */
96 KIRQL WaitIrql; /* 54 */
97 UCHAR WaitMode; /* 55 */
98 UCHAR WaitNext; /* 56 */
99 UCHAR WaitReason; /* 57 */
100 PKWAIT_BLOCK WaitBlockList; /* 58 */
101 LIST_ENTRY WaitListEntry; /* 5C */
102 ULONG WaitTime; /* 64 */
103 CHAR BasePriority; /* 68 */
104 UCHAR DecrementCount; /* 69 */
105 UCHAR PriorityDecrement; /* 6A */
106 UCHAR Quantum; /* 6B */
107 KWAIT_BLOCK WaitBlock[4]; /* 6C */
108 PVOID LegoData; /* CC */
109 LONG KernelApcDisable; /* D0 */
110 KAFFINITY UserAffinity; /* D4 */
111 UCHAR SystemAffinityActive;/* D8 */
112 UCHAR PowerState; /* D9 */
113 UCHAR NpxIrql; /* DA */
115 SSDT_ENTRY *ServiceTable; /* DC */
116 PKQUEUE Queue; /* E0 */
117 KSPIN_LOCK ApcQueueLock; /* E4 */
118 KTIMER Timer; /* E8 */
119 LIST_ENTRY QueueListEntry; /* 110 */
120 KAFFINITY Affinity; /* 118 */
121 UCHAR Preempted; /* 11C */
122 UCHAR ProcessReadyQueue; /* 11D */
123 UCHAR KernelStackResident; /* 11E */
124 UCHAR NextProcessor; /* 11F */
125 PVOID CallbackStack; /* 120 */
126 BOOL Win32Thread; /* 124 */
127 struct _KTRAP_FRAME* TrapFrame; /* 128 */
128 PVOID ApcStatePointer[2]; /* 12C */
129 UCHAR EnableStackSwap; /* 134 */
130 UCHAR LargeStack; /* 135 */
131 UCHAR ResourceIndex; /* 136 */
132 UCHAR PreviousMode; /* 137 */
133 ULONG KernelTime; /* 138 */
134 ULONG UserTime; /* 13C */
135 KAPC_STATE SavedApcState; /* 140 */
136 UCHAR Alertable; /* 158 */
137 UCHAR ApcStateIndex; /* 159 */
138 UCHAR ApcQueueable; /* 15A */
139 UCHAR AutoAlignment; /* 15B */
140 PVOID StackBase; /* 15C */
141 KAPC SuspendApc; /* 160 */
142 KSEMAPHORE SuspendSemaphore; /* 190 */
143 LIST_ENTRY ThreadListEntry; /* 1A4 */
144 CHAR FreezeCount; /* 1AC */
145 UCHAR SuspendCount; /* 1AD */
146 UCHAR IdealProcessor; /* 1AE */
147 UCHAR DisableBoost; /* 1AF */
150 * Below here are thread structure members that are specific to ReactOS
153 /* Added by Phillip Susi for list of threads in a process */
154 LIST_ENTRY ProcessThreadListEntry; /* 1B0 */
155 } __attribute__((packed)) KTHREAD;
157 /* Top level irp definitions. */
158 #define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
159 #define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
160 #define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
161 #define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
162 #define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
164 typedef struct _TOP_LEVEL_IRP
167 ULONG TopLevelIrpConst;
172 PACCESS_TOKEN Token; // 0x0
173 UCHAR Unknown1; // 0x4
174 UCHAR Unknown2; // 0x5
176 SECURITY_IMPERSONATION_LEVEL Level; // 0x8
177 } PS_IMPERSONATION_INFO, *PPS_IMPERSONATION_INFO;
179 typedef struct _ETHREAD
181 KTHREAD Tcb; /* 000 */
182 TIME CreateTime; /* 1B0/1B8 */
185 TIME ExitTime; /* 1B8/1E4 */
186 LIST_ENTRY LpcReplyChain; /* 1B8/1E4 */
188 NTSTATUS ExitStatus; /* 1C0/1EC */
189 LIST_ENTRY PostBlockList; /* 1C4/1F0 */
190 LIST_ENTRY TerminationPortList; /* 1CC/1F8 */
191 KSPIN_LOCK ActiveTimerListLock; /* 1D4/200 */
192 LIST_ENTRY ActiveTimerListHead; /* 1D8/204 */
193 CLIENT_ID Cid; /* 1E0/20C */
194 KSEMAPHORE LpcReplySemaphore; /* 1E8/214 */
195 PVOID LpcReplyMessage; /* 1FC/228 */
196 PLARGE_INTEGER LpcReplyMessageId; /* 200/22C */
197 ULONG PerformanceCounterLow; /* 204/230 */
198 PPS_IMPERSONATION_INFO ImpersonationInfo; /* 208/234 */
199 LIST_ENTRY IrpList; /* 20C/238 */
200 TOP_LEVEL_IRP* TopLevelIrp; /* 214/240 */
201 PDEVICE_OBJECT DeviceToVerify; /* 218/244 */
202 ULONG ReadClusterSize; /* 21C/248 */
203 UCHAR ForwardClusterOnly; /* 220/24C */
204 UCHAR DisablePageFaultClustering; /* 221/24D */
205 UCHAR DeadThread; /* 222/24E */
206 UCHAR HasTerminated; /* 223/24F */
207 PVOID EventPair; /* 224/250 */
208 ACCESS_MASK GrantedAccess; /* 228/254 */
209 struct _EPROCESS* ThreadsProcess; /* 22C/258 */
210 PKSTART_ROUTINE StartAddress; /* 230/25C */
213 LPTHREAD_START_ROUTINE Win32StartAddress; /* 234/260 */
214 ULONG LpcReceiveMessageId; /* 234/260 */
216 UCHAR LpcExitThreadCalled; /* 238/264 */
217 UCHAR HardErrorsAreDisabled; /* 239/265 */
218 UCHAR LpcReceivedMsgIdValid; /* 23A/266 */
219 UCHAR ActiveImpersonationInfo; /* 23B/267 */
220 ULONG PerformanceCountHigh; /* 23C/268 */
223 * Added by David Welch (welch@cwcom.net)
225 struct _EPROCESS* OldProcess; /* 240/26C */
227 struct _W32THREAD* Win32Thread;
229 } __attribute__((packed)) ETHREAD;
233 #if 0 /* Currently defined by <ddk/iofuncs.h> */
234 typedef struct _ETHREAD *PETHREAD;
236 #include <ddk/iofuncs.h>
238 #endif /* __USE_W32API */
241 typedef struct _KPROCESS
243 /* So it's possible to wait for the process to terminate */
244 DISPATCHER_HEADER DispatcherHeader; /* 000 */
246 * Presumably a list of profile objects associated with this process,
249 LIST_ENTRY ProfileListHead; /* 010 */
251 * We use the first member of this array to hold the physical address of
252 * the page directory for this process.
254 PHYSICAL_ADDRESS DirectoryTableBase; /* 018 */
256 * Presumably a descriptor for the process's LDT, currently unused.
258 ULONG LdtDescriptor[2]; /* 020 */
260 * Virtual Dos Machine flag.
262 ULONG NtVdmFlag; /* 028 */
263 ULONG VdmUnused; /* 02C */
264 /* Is the i/o permission map enabled for the process. */
265 USHORT IopmOffset; /* 030 */
267 * Presumably I/O privilege level to be used for this process, currently
270 UCHAR Iopl; /* 032 */
271 /* Set if this process is a virtual dos machine? */
272 UCHAR VdmFlag; /* 033 */
273 /* Bitmask of the processors being used by this process's threads? */
274 ULONG ActiveProcessors; /* 034 */
275 /* Aggregate of the time this process's threads have spent in kernel mode? */
276 ULONG KernelTime; /* 038 */
277 /* Aggregate of the time this process's threads have spent in user mode? */
278 ULONG UserTime; /* 03C */
279 /* List of this process's threads that are ready for execution? */
280 LIST_ENTRY ReadyListHead; /* 040 */
281 /* List of this process's threads that have their stacks swapped out? */
282 LIST_ENTRY SwapListEntry; /* 048 */
283 /* List of this process's threads? */
284 LIST_ENTRY ThreadListHead; /* 050 */
285 /* Maybe a lock for this data structure, the type is assumed. */
286 KSPIN_LOCK ProcessLock; /* 058 */
287 /* Default affinity mask for this process's threads? */
288 ULONG Affinity; /* 05C */
289 /* Count of the stacks allocated for this process's threads? */
290 USHORT StackCount; /* 060 */
291 /* Base priority for this process's threads? */
292 KPRIORITY BasePriority; /* 062 */
293 /* Default quantum for this process's threads */
294 UCHAR ThreadQuantum; /* 063 */
296 UCHAR AutoAlignment; /* 064 */
297 /* Process execution state, currently either active or terminated. */
298 UCHAR State; /* 065 */
299 /* Seed for generating thread ids for this process's threads? */
300 UCHAR ThreadSeed; /* 066 */
301 /* Disable priority boosts? */
302 UCHAR DisableBoost; /* 067 */
307 typedef struct _KPROCESS *PKPROCESS;
309 #endif /* __USE_W32API */
313 /* Microkernel specific process state. */
314 KPROCESS Pcb; /* 000 */
315 /* Exit status of the process. */
316 NTSTATUS ExitStatus; /* 068 */
318 KEVENT LockEvent; /* 06C */
320 ULONG LockCount; /* 07C */
322 /* Time of process creation. */
324 LARGE_INTEGER CreateTime; /* 080 */
326 TIME CreateTime; /* 080 */
329 /* Time of process exit. */
330 TIME ExitTime; /* 088 */
332 PVOID LockOwner; /* 090 */
334 ULONG UniqueProcessId; /* 094 */
336 LIST_ENTRY ActiveProcessLinks; /* 098 */
338 ULONG QuotaPeakPoolUsage[2]; /* 0A0 */
340 ULONG QuotaPoolUsage[2]; /* 0A8 */
342 ULONG PagefileUsage; /* 0B0 */
344 ULONG CommitCharge; /* 0B4 */
346 ULONG PeakPagefileUsage; /* 0B8 */
348 ULONG PeakVirtualSize; /* 0BC */
350 LARGE_INTEGER VirtualSize; /* 0C0 */
354 ULONG LastTrimFaultCount;
355 ULONG PageFaultCount;
356 ULONG PeakWorkingSetSize;
357 ULONG WorkingSetSize;
358 ULONG MinimumWorkingSetSize;
359 ULONG MaximumWorkingSetSize;
360 ULONG VmWorkingSetList;
361 LIST_ENTRY WorkingSetExpansionList;
362 UCHAR AllowWorkingSetAdjustment;
363 UCHAR AddressSpaceBeingDeleted;
364 UCHAR ForegroundPrioritySwitch;
365 UCHAR MemoryPriority;
367 PVOID LastProtoPteFault;
368 struct _EPORT* DebugPort;
369 struct _EPORT* ExceptionPort;
372 /* FAST_MUTEX WorkingSetLock; */
373 KMUTEX WorkingSetLock;
374 PVOID WorkingSetPage;
375 UCHAR ProcessOutswapEnabled;
376 UCHAR ProcessOutswapped;
377 UCHAR AddressSpaceInitialized;
378 UCHAR AddressSpaceDeleted;
379 FAST_MUTEX AddressCreationLock;
380 KSPIN_LOCK HyperSpaceLock;
381 PETHREAD ForkInProgress;
383 UCHAR ForkWasSuccessful;
384 UCHAR MmAgressiveWsTrimMask;
385 PKEVENT VmOperationEvent;
386 PVOID PageDirectoryPte;
387 ULONG LastFaultCount;
391 ULONG NumberOfPrivatePages;
392 ULONG NumberOfLockedPages;
393 USHORT NextProcessColour;
394 UCHAR ExitProcessCalled;
395 UCHAR CreateProcessReported;
396 HANDLE SectionHandle;
398 PVOID SectionBaseAddress;
400 NTSTATUS LastThreadExitStatus;
401 PVOID WorkingSetWatch;
402 HANDLE InheritedFromUniqueProcessId;
403 ACCESS_MASK GrantedAccess;
404 ULONG DefaultHardErrorProcessing;
405 PVOID LdtInformation;
408 KMUTANT ProcessMutant;
409 CHAR ImageFileName[16];
410 ULONG VmTrimFaultValue;
411 UCHAR SetTimerResolution;
413 UCHAR SubSystemMinorVersion;
414 UCHAR SubSystemMajorVersion;
415 USHORT SubSystemVersion;
416 struct _W32PROCESS* Win32Process;
417 HANDLE Win32WindowStation;
420 * Added by David Welch (welch@mcmail.com)
423 MADDRESS_SPACE AddressSpace;
424 HANDLE_TABLE HandleTable;
425 LIST_ENTRY ProcessListEntry;
428 * Added by Philip Susi for list of threads in process
430 LIST_ENTRY ThreadListHead;
433 #define PROCESS_STATE_TERMINATED (1)
434 #define PROCESS_STATE_ACTIVE (2)
436 VOID PiInitDefaultLocale(VOID);
437 VOID PiInitProcessManager(VOID);
438 VOID PiShutdownProcessManager(VOID);
439 VOID PsInitThreadManagment(VOID);
440 VOID PsInitProcessManagment(VOID);
441 VOID PsInitIdleThread(VOID);
442 VOID PsDispatchThreadNoLock(ULONG NewThreadStatus);
443 VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
444 VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus);
445 VOID PsReleaseThread(PETHREAD Thread);
446 VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
447 VOID PsBeginThreadWithContextInternal(VOID);
448 VOID PiKillMostProcesses(VOID);
449 NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process, NTSTATUS ExitStatus);
450 VOID PiInitApcManagement(VOID);
451 VOID STDCALL PiDeleteThread(PVOID ObjectBody);
452 VOID PsReapThreads(VOID);
454 PsInitializeThread(HANDLE ProcessHandle,
456 PHANDLE ThreadHandle,
457 ACCESS_MASK DesiredAccess,
458 POBJECT_ATTRIBUTES ObjectAttributes,
461 PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
462 PTOKEN_TYPE TokenType,
464 PSECURITY_IMPERSONATION_LEVEL Level);
466 NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
467 PACCESS_TOKEN* Token);
469 NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
470 NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
473 #define THREAD_STATE_INITIALIZED (0)
474 #define THREAD_STATE_READY (1)
475 #define THREAD_STATE_RUNNING (2)
476 #define THREAD_STATE_SUSPENDED (3)
477 #define THREAD_STATE_FROZEN (4)
478 #define THREAD_STATE_TERMINATED_1 (5)
479 #define THREAD_STATE_TERMINATED_2 (6)
480 #define THREAD_STATE_BLOCKED (7)
481 #define THREAD_STATE_MAX (8)
485 * Internal thread priorities, added by Phillip Susi
486 * TODO: rebalence these to make use of all priorities... the ones above 16
487 * can not all be used right now
489 #define PROCESS_PRIO_IDLE 3
490 #define PROCESS_PRIO_NORMAL 8
491 #define PROCESS_PRIO_HIGH 13
492 #define PROCESS_PRIO_RT 18
496 KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
497 NTSTATUS KeReleaseThread(PETHREAD Thread);
498 VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
499 VOID PsReapThreads(VOID);
500 VOID PsUnfreezeOtherThread(PETHREAD Thread);
501 VOID PsFreezeOtherThread(PETHREAD Thread);
502 VOID PsFreezeProcessThreads(PEPROCESS Process);
503 VOID PsUnfreezeProcessThreads(PEPROCESS Process);
504 PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
506 PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
507 BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason);
509 PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus);
511 PsApplicationProcessorInit(VOID);
513 PsPrepareForApplicationProcessorInit(ULONG Id);
515 PsIdleThreadMain(PVOID Context);
518 PiSuspendThreadRundownRoutine(PKAPC Apc);
520 PiSuspendThreadKernelRoutine(PKAPC Apc,
521 PKNORMAL_ROUTINE* NormalRoutine,
522 PVOID* NormalContext,
523 PVOID* SystemArgument1,
524 PVOID* SystemArguemnt2);
526 PiSuspendThreadNormalRoutine(PVOID NormalContext,
527 PVOID SystemArgument1,
528 PVOID SystemArgument2);
530 PsDispatchThread(ULONG NewThreadStatus);
532 PsInitialiseSuspendImplementation(VOID);
534 extern ULONG PiNrThreadsAwaitingReaping;
538 PsInitWin32Thread (PETHREAD Thread);
541 PsTerminateWin32Process (PEPROCESS Process);
544 PsTerminateWin32Thread (PETHREAD Thread);
547 PsInitialiseW32Call(VOID);
549 #endif /* ASSEMBLER */
551 #endif /* __INCLUDE_INTERNAL_PS_H */