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.
19 /* $Id: ps.h,v 1.32 2002/05/13 18:10:39 chorns Exp $
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
32 * Defines for accessing KPCR and KTHREAD structure members
34 #define KTHREAD_INITIAL_STACK 0x18
35 #define KTHREAD_TEB 0x20
36 #define KTHREAD_KERNEL_STACK 0x28
37 #define KTHREAD_PREVIOUS_MODE 0x137
38 #define KTHREAD_TRAP_FRAME 0x128
39 #define KTHREAD_CALLBACK_STACK 0x120
41 #define ETHREAD_THREADS_PROCESS 0x258
43 #define KPROCESS_DIRECTORY_TABLE_BASE 0x18
45 #define KPCR_BASE 0xFF000000
47 #define KPCR_EXCEPTION_LIST 0x0
48 #define KPCR_SELF 0x18
50 #define KPCR_CURRENT_THREAD 0x124
54 #include <internal/mm.h>
60 /* FIXME: This does not work if we have more than 24 IRQs (ie. more than one I/O APIC) */
61 #define VECTOR2IRQ(vector) (((vector) - 0x31) / 8)
62 #define VECTOR2IRQL(vector) (4 + VECTOR2IRQ(vector))
65 * Processor Control Region
69 PVOID ExceptionList
; /* 00 */
70 PVOID StackBase
; /* 04 */
71 PVOID StackLimit
; /* 08 */
72 PVOID SubSystemTib
; /* 0C */
73 PVOID Reserved1
; /* 10 */
74 PVOID ArbitraryUserPointer
; /* 14 */
75 struct _KPCR
* Self
; /* 18 */
76 UCHAR ProcessorNumber
; /* 1C */
78 UCHAR Reserved2
[0x2]; /* 1E */
82 UCHAR Reserved3
[0xF8]; /* 2C */
83 struct _KTHREAD
* CurrentThread
; /* 124 */
84 } __attribute__((packed
)) KPCR
, *PKPCR
;
86 static inline PKPCR
KeGetCurrentKPCR(VOID
)
90 __asm__
__volatile__ ("movl %%fs:0x18, %0\n\t"
97 #define KeGetCurrentProcessorNumber() (KeGetCurrentKPCR()->ProcessorNumber)
99 extern HANDLE SystemProcessHandle
;
101 extern LCID PsDefaultThreadLocaleId
;
102 extern LCID PsDefaultSystemLocaleId
;
105 typedef struct _KAPC_STATE
107 LIST_ENTRY ApcListHead
[2];
108 struct _KPROCESS
* Process
;
109 UCHAR KernelApcInProgress
;
110 UCHAR KernelApcPending
;
111 USHORT UserApcPending
;
112 } __attribute__((packed
)) KAPC_STATE
, *PKAPC_STATE
;
114 typedef struct _KTHREAD
116 /* For waiting on thread exit */
117 DISPATCHER_HEADER DispatcherHeader
; /* 00 */
119 /* List of mutants owned by the thread */
120 LIST_ENTRY MutantListHead
; /* 10 */
121 PVOID InitialStack
; /* 18 */
122 ULONG StackLimit
; /* 1C */
124 /* Pointer to the thread's environment block in user memory */
127 /* Pointer to the thread's TLS array */
128 PVOID TlsArray
; /* 24 */
129 PVOID KernelStack
; /* 28 */
130 UCHAR DebugActive
; /* 2C */
132 /* Thread state (one of THREAD_STATE_xxx constants below) */
133 UCHAR State
; /* 2D */
134 UCHAR Alerted
[2]; /* 2E */
136 UCHAR NpxState
; /* 31 */
137 UCHAR Saturation
; /* 32 */
138 CHAR Priority
; /* 33 */
139 KAPC_STATE ApcState
; /* 34 */
140 ULONG ContextSwitches
; /* 4C */
141 ULONG WaitStatus
; /* 50 */
142 KIRQL WaitIrql
; /* 54 */
143 UCHAR WaitMode
; /* 55 */
144 UCHAR WaitNext
; /* 56 */
145 UCHAR WaitReason
; /* 57 */
146 PKWAIT_BLOCK WaitBlockList
; /* 58 */
147 LIST_ENTRY WaitListEntry
; /* 5C */
148 ULONG WaitTime
; /* 64 */
149 CHAR BasePriority
; /* 68 */
150 UCHAR DecrementCount
; /* 69 */
151 UCHAR PriorityDecrement
; /* 6A */
152 UCHAR Quantum
; /* 6B */
153 KWAIT_BLOCK WaitBlock
[4]; /* 6C */
154 PVOID LegoData
; /* CC */
155 LONG KernelApcDisable
; /* D0 */
156 KAFFINITY UserAffinity
; /* D4 */
157 UCHAR SystemAffinityActive
;/* D8 */
158 UCHAR Pad
[7]; /* D9 */
159 PKQUEUE Queue
; /* E0 */
160 KSPIN_LOCK ApcQueueLock
; /* E4 */
161 KTIMER Timer
; /* E8 */
162 LIST_ENTRY QueueListEntry
; /* 110 */
163 KAFFINITY Affinity
; /* 118 */
164 UCHAR Preempted
; /* 11C */
165 UCHAR ProcessReadyQueue
; /* 11D */
166 UCHAR KernelStackResident
; /* 11E */
167 UCHAR NextProcessor
; /* 11F */
168 PVOID CallbackStack
; /* 120 */
169 BOOL Win32Thread
; /* 124 */
170 struct _KTRAP_FRAME
* TrapFrame
; /* 128 */
171 PVOID ApcStatePointer
[2]; /* 12C */
172 UCHAR EnableStackSwap
; /* 134 */
173 UCHAR LargeStack
; /* 135 */
174 UCHAR ResourceIndex
; /* 136 */
175 UCHAR PreviousMode
; /* 137 */
176 ULONG KernelTime
; /* 138 */
177 ULONG UserTime
; /* 13C */
178 KAPC_STATE SavedApcState
; /* 140 */
179 UCHAR Alertable
; /* 158 */
180 UCHAR ApcStateIndex
; /* 159 */
181 UCHAR ApcQueueable
; /* 15A */
182 UCHAR AutoAlignment
; /* 15B */
183 PVOID StackBase
; /* 15C */
184 KAPC SuspendApc
; /* 160 */
185 KSEMAPHORE SuspendSemaphore
; /* 190 */
186 LIST_ENTRY ThreadListEntry
; /* 1A4 */
187 CHAR FreezeCount
; /* 1AC */
188 UCHAR SuspendCount
; /* 1AD */
189 UCHAR IdealProcessor
; /* 1AE */
190 UCHAR DisableBoost
; /* 1AF */
193 * Below here are thread structure members that are specific to ReactOS
196 /* Added by Phillip Susi for list of threads in a process */
197 LIST_ENTRY ProcessThreadListEntry
; /* 1B0 */
199 /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */
200 KDPC TimerDpc
; /* 1B8 */
202 /* Record the last EIP value when the thread is suspended */
203 ULONG LastEip
; /* 1D8 */
204 } __attribute__((packed
)) KTHREAD
, *PKTHREAD
;
206 // According to documentation the stack should have a commited [ 1 page ] and
207 // a reserved part [ 1 M ] but can be specified otherwise in the image file.
215 // TopLevelIrp can be one of the following values:
216 // FIXME I belong somewhere else
218 #define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
219 #define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
220 #define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
221 #define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
222 #define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
224 typedef struct _TOP_LEVEL_IRP
227 ULONG TopLevelIrpConst
;
232 PACCESS_TOKEN Token
; // 0x0
233 UCHAR Unknown1
; // 0x4
234 UCHAR Unknown2
; // 0x5
236 SECURITY_IMPERSONATION_LEVEL Level
; // 0x8
237 } PS_IMPERSONATION_INFO
, *PPS_IMPERSONATION_INFO
;
240 typedef struct _ETHREAD
242 KTHREAD Tcb
; /* 000 */
243 TIME CreateTime
; /* 1B0/1DC */
246 TIME ExitTime
; /* 1B8/1E4 */
247 LIST_ENTRY LpcReplyChain
; /* 1B8/1E4 */
249 NTSTATUS ExitStatus
; /* 1C0/1EC */
250 LIST_ENTRY PostBlockList
; /* 1C4/1F0 */
251 LIST_ENTRY TerminationPortList
; /* 1CC/1F8 */
252 KSPIN_LOCK ActiveTimerListLock
; /* 1D4/200 */
253 LIST_ENTRY ActiveTimerListHead
; /* 1D8/204 */
254 CLIENT_ID Cid
; /* 1E0/20C */
255 KSEMAPHORE LpcReplySemaphore
; /* 1E8/214 */
256 PVOID LpcReplyMessage
; /* 1FC/228 */
257 PLARGE_INTEGER LpcReplyMessageId
; /* 200/22C */
258 ULONG PerformanceCounterLow
; /* 204/230 */
259 PPS_IMPERSONATION_INFO ImpersonationInfo
; /* 208/234 */
260 LIST_ENTRY IrpList
; /* 20C/238 */
261 TOP_LEVEL_IRP
* TopLevelIrp
; /* 214/240 */
262 PDEVICE_OBJECT DeviceToVerify
; /* 218/244 */
263 ULONG ReadClusterSize
; /* 21C/248 */
264 UCHAR ForwardClusterOnly
; /* 220/24C */
265 UCHAR DisablePageFaultClustering
; /* 221/24D */
266 UCHAR DeadThread
; /* 222/24E */
267 UCHAR HasTerminated
; /* 223/24F */
268 PVOID EventPair
; /* 224/250 */
269 ACCESS_MASK GrantedAccess
; /* 228/254 */
270 struct _EPROCESS
* ThreadsProcess
; /* 22C/258 */
271 PKSTART_ROUTINE StartAddress
; /* 230/25C */
274 LPTHREAD_START_ROUTINE Win32StartAddress
; /* 234/260 */
275 ULONG LpcReceiveMessageId
; /* 234/260 */
277 UCHAR LpcExitThreadCalled
; /* 238/264 */
278 UCHAR HardErrorsAreDisabled
; /* 239/265 */
279 UCHAR LpcReceivedMsgIdValid
; /* 23A/266 */
280 UCHAR ActiveImpersonationInfo
; /* 23B/267 */
281 ULONG PerformanceCountHigh
; /* 23C/268 */
284 * Added by David Welch (welch@cwcom.net)
286 struct _EPROCESS
* OldProcess
; /* 240/26C */
288 struct _W32THREAD
* Win32Thread
;
290 } __attribute__((packed
)) ETHREAD
, *PETHREAD
;
293 typedef struct _KPROCESS
295 /* So it's possible to wait for the process to terminate */
296 DISPATCHER_HEADER DispatcherHeader
; /* 000 */
298 * Presumably a list of profile objects associated with this process,
301 LIST_ENTRY ProfileListHead
; /* 010 */
303 * We use the first member of this array to hold the physical address of
304 * the page directory for this process.
306 PVOID DirectoryTableBase
[2]; /* 018 */
308 * Presumably a descriptor for the process's LDT, currently unused.
310 ULONG LdtDescriptor
[2]; /* 020 */
312 * Presumably for processing int 0x21 from V86 mode DOS, currently
315 ULONG Int21Descriptor
[2]; /* 028 */
317 USHORT IopmOffset
; /* 030 */
319 * Presumably I/O privilege level to be used for this process, currently
322 UCHAR Iopl
; /* 032 */
323 /* Set if this process is a virtual dos machine? */
324 UCHAR VdmFlag
; /* 033 */
325 /* Bitmask of the processors being used by this process's threads? */
326 ULONG ActiveProcessors
; /* 034 */
327 /* Aggregate of the time this process's threads have spent in kernel mode? */
328 ULONG KernelTime
; /* 038 */
329 /* Aggregate of the time this process's threads have spent in user mode? */
330 ULONG UserTime
; /* 03C */
331 /* List of this process's threads that are ready for execution? */
332 LIST_ENTRY ReadyListHead
; /* 040 */
333 /* List of this process's threads that have their stacks swapped out? */
334 LIST_ENTRY SwapListEntry
; /* 048 */
335 /* List of this process's threads? */
336 LIST_ENTRY ThreadListHead
; /* 050 */
337 /* Maybe a lock for this data structure, the type is assumed. */
338 KSPIN_LOCK ProcessLock
; /* 058 */
339 /* Default affinity mask for this process's threads? */
340 ULONG Affinity
; /* 05C */
341 /* Count of the stacks allocated for this process's threads? */
342 USHORT StackCount
; /* 060 */
343 /* Base priority for this process's threads? */
344 KPRIORITY BasePriority
; /* 062 */
345 /* Default quantum for this process's threads */
346 UCHAR ThreadQuantum
; /* 063 */
348 UCHAR AutoAlignment
; /* 064 */
349 /* Process execution state, currently either active or terminated. */
350 UCHAR State
; /* 065 */
351 /* Seed for generating thread ids for this process's threads? */
352 UCHAR ThreadSeed
; /* 066 */
353 /* Disable priority boosts? */
354 UCHAR DisableBoost
; /* 067 */
355 } KPROCESS
, *PKPROCESS
;
359 /* Microkernel specific process state. */
360 KPROCESS Pcb
; /* 000 */
361 /* Exit status of the process. */
362 NTSTATUS ExitStatus
; /* 068 */
364 KEVENT LockEvent
; /* 06C */
366 ULONG LockCount
; /* 07C */
367 /* Time of process creation. */
368 TIME CreateTime
; /* 080 */
369 /* Time of process exit. */
370 TIME ExitTime
; /* 088 */
372 PVOID LockOwner
; /* 090 */
374 ULONG UniqueProcessId
; /* 094 */
376 LIST_ENTRY ActiveProcessLinks
; /* 098 */
378 ULONG QuotaPeakPoolUsage
[2]; /* 0A0 */
380 ULONG QuotaPoolUsage
[2]; /* 0A8 */
382 ULONG PagefileUsage
; /* 0B0 */
384 ULONG CommitCharge
; /* 0B4 */
386 ULONG PeakPagefileUsage
; /* 0B8 */
388 ULONG PeakVirtualSize
; /* 0BC */
390 LARGE_INTEGER VirtualSize
; /* 0C0 */
394 ULONG LastTrimFaultCount
;
395 ULONG PageFaultCount
;
396 ULONG PeakWorkingSetSize
;
397 ULONG WorkingSetSize
;
398 ULONG MinimumWorkingSetSize
;
399 ULONG MaximumWorkingSetSize
;
400 ULONG VmWorkingSetList
;
401 LIST_ENTRY WorkingSetExpansionList
;
402 UCHAR AllowWorkingSetAdjustment
;
403 UCHAR AddressSpaceBeingDeleted
;
404 UCHAR ForegroundPrioritySwitch
;
405 UCHAR MemoryPriority
;
407 PVOID LastProtoPteFault
;
408 struct _EPORT
* DebugPort
;
409 struct _EPORT
* ExceptionPort
;
412 // FAST_MUTEX WorkingSetLock;
413 KMUTEX WorkingSetLock
;
414 PVOID WorkingSetPage
;
415 UCHAR ProcessOutswapEnabled
;
416 UCHAR ProcessOutswapped
;
417 UCHAR AddressSpaceInitialized
;
418 UCHAR AddressSpaceDeleted
;
419 FAST_MUTEX AddressCreationLock
;
420 KSPIN_LOCK HyperSpaceLock
;
421 PETHREAD ForkInProgress
;
423 UCHAR ForkWasSuccessful
;
424 UCHAR MmAgressiveWsTrimMask
;
425 PKEVENT VmOperationEvent
;
426 PVOID PageDirectoryPte
;
427 ULONG LastFaultCount
;
431 ULONG NumberOfPrivatePages
;
432 ULONG NumberOfLockedPages
;
433 USHORT NextProcessColour
;
434 UCHAR ExitProcessCalled
;
435 UCHAR CreateProcessReported
;
436 HANDLE SectionHandle
;
438 PVOID SectionBaseAddress
;
440 NTSTATUS LastThreadExitStatus
;
441 PVOID WorkingSetWatch
;
442 HANDLE InheritedFromUniqueProcessId
;
443 ACCESS_MASK GrantedAccess
;
444 ULONG DefaultHardErrorProcessing
;
445 PVOID LdtInformation
;
448 KMUTANT ProcessMutant
;
449 CHAR ImageFileName
[16];
450 ULONG VmTrimFaultValue
;
451 UCHAR SetTimerResolution
;
453 UCHAR SubSystemMinorVersion
;
454 UCHAR SubSystemMajorVersion
;
455 USHORT SubSystemVersion
;
456 struct _W32PROCESS
* Win32Process
;
457 HANDLE Win32WindowStation
;
460 * Added by David Welch (welch@mcmail.com)
462 MADDRESS_SPACE AddressSpace
;
463 HANDLE_TABLE HandleTable
;
464 LIST_ENTRY ProcessListEntry
;
467 * Added by Philip Susi for list of threads in process
469 LIST_ENTRY ThreadListHead
;
472 #define PROCESS_STATE_TERMINATED (1)
473 #define PROCESS_STATE_ACTIVE (2)
475 VOID
PiInitDefaultLocale(VOID
);
476 VOID
PiInitProcessManager(VOID
);
477 VOID
PiShutdownProcessManager(VOID
);
478 VOID
PsInitThreadManagment(VOID
);
479 VOID
PsInitProcessManagment(VOID
);
480 VOID
PsInitIdleThread(VOID
);
481 VOID
PsDispatchThreadNoLock(ULONG NewThreadStatus
);
482 VOID
PiTerminateProcessThreads(PEPROCESS Process
, NTSTATUS ExitStatus
);
483 VOID
PsTerminateOtherThread(PETHREAD Thread
, NTSTATUS ExitStatus
);
484 VOID
PsReleaseThread(PETHREAD Thread
);
485 VOID
PsBeginThread(PKSTART_ROUTINE StartRoutine
, PVOID StartContext
);
486 VOID
PsBeginThreadWithContextInternal(VOID
);
487 VOID
PiKillMostProcesses(VOID
);
488 NTSTATUS STDCALL
PiTerminateProcess(PEPROCESS Process
, NTSTATUS ExitStatus
);
489 ULONG
PsUnfreezeThread(PETHREAD Thread
, PNTSTATUS WaitStatus
);
490 ULONG
PsFreezeThread(PETHREAD Thread
, PNTSTATUS WaitStatus
,
491 UCHAR Alertable
, ULONG WaitMode
);
492 VOID
PiInitApcManagement(VOID
);
493 VOID STDCALL
PiDeleteThread(PVOID ObjectBody
);
494 VOID STDCALL
PiCloseThread(PVOID ObjectBody
, ULONG HandleCount
);
495 VOID
PsReapThreads(VOID
);
497 PsInitializeThread(HANDLE ProcessHandle
,
499 PHANDLE ThreadHandle
,
500 ACCESS_MASK DesiredAccess
,
501 POBJECT_ATTRIBUTES ObjectAttributes
,
504 PACCESS_TOKEN
PsReferenceEffectiveToken(PETHREAD Thread
,
505 PTOKEN_TYPE TokenType
,
507 PSECURITY_IMPERSONATION_LEVEL Level
);
509 NTSTATUS
PsOpenTokenOfProcess(HANDLE ProcessHandle
,
510 PACCESS_TOKEN
* Token
);
512 NTSTATUS
PsSuspendThread(PETHREAD Thread
, PULONG PreviousCount
);
513 NTSTATUS
PsResumeThread(PETHREAD Thread
, PULONG PreviousCount
);
516 #define THREAD_STATE_INVALID (0)
517 #define THREAD_STATE_RUNNABLE (1)
518 #define THREAD_STATE_RUNNING (2)
519 #define THREAD_STATE_SUSPENDED (3)
520 #define THREAD_STATE_FROZEN (4)
521 #define THREAD_STATE_TERMINATED_1 (5)
522 #define THREAD_STATE_TERMINATED_2 (6)
523 #define THREAD_STATE_BLOCKED (7)
524 #define THREAD_STATE_MAX (8)
528 * Internal thread priorities, added by Phillip Susi
529 * TODO: rebalence these to make use of all priorities... the ones above 16 can not all be used right now
532 #define PROCESS_PRIO_IDLE 3
533 #define PROCESS_PRIO_NORMAL 8
534 #define PROCESS_PRIO_HIGH 13
535 #define PROCESS_PRIO_RT 18
539 KeInitializeThread(PKPROCESS Process
, PKTHREAD Thread
, BOOLEAN First
);
540 NTSTATUS
KeReleaseThread(PETHREAD Thread
);
542 Ke386InitThread(PKTHREAD Thread
, PKSTART_ROUTINE fn
, PVOID StartContext
);
544 Ke386InitThreadWithContext(PKTHREAD Thread
, PCONTEXT Context
);
545 VOID STDCALL
PiDeleteProcess(PVOID ObjectBody
);
546 VOID
PsReapThreads(VOID
);
547 VOID
PsUnfreezeOtherThread(PETHREAD Thread
);
548 VOID
PsFreezeOtherThread(PETHREAD Thread
);
549 VOID
PsFreezeProcessThreads(PEPROCESS Process
);
550 VOID
PsUnfreezeProcessThreads(PEPROCESS Process
);
551 PEPROCESS
PsGetNextProcess(PEPROCESS OldProcess
);
553 Ki386ContextSwitch(PKTHREAD NewThread
, PKTHREAD OldThread
);
555 PsBlockThread(PNTSTATUS Status
, UCHAR Alertable
, ULONG WaitMode
,
556 BOOLEAN DispatcherLock
, KIRQL WaitIrql
);
558 PsUnblockThread(PETHREAD Thread
, PNTSTATUS WaitStatus
);
560 PsApplicationProcessorInit(VOID
);
562 PsPrepareForApplicationProcessorInit(ULONG Id
);
564 PsIdleThreadMain(PVOID Context
);
567 PiSuspendThreadRundownRoutine(PKAPC Apc
);
569 PiSuspendThreadKernelRoutine(PKAPC Apc
,
570 PKNORMAL_ROUTINE
* NormalRoutine
,
571 PVOID
* NormalContext
,
572 PVOID
* SystemArgument1
,
573 PVOID
* SystemArguemnt2
);
575 PiSuspendThreadNormalRoutine(PVOID NormalContext
,
576 PVOID SystemArgument1
,
577 PVOID SystemArgument2
);
580 PiTimeoutThread(struct _KDPC
*dpc
,
586 PsDispatchThread(ULONG NewThreadStatus
);
589 PiSetPriorityThread(IN HANDLE ThreadHandle
,
590 IN KPRIORITY Priority
);
592 #endif /* ASSEMBLER */
594 #endif /* __INCLUDE_INTERNAL_PS_H */