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: Microkernel thread support
22 * PROGRAMMER: David Welch (welch@cwcom.net)
27 /* INCLUDES *****************************************************************/
29 #include <ddk/ntddk.h>
30 #include <internal/ke.h>
31 #include <internal/ps.h>
32 #include <internal/id.h>
33 #include <internal/pool.h>
36 #include <internal/debug.h>
38 /* EXTERN ********************************************************************/
41 PiTimeoutThread(struct _KDPC Dpc
, PVOID Context
, PVOID Arg1
, PVOID Arg2
);
43 PiSuspendThreadRundownRoutine(PKAPC Apc
);
45 PiSuspendThreadKernelRoutine(PKAPC Apc
,
46 PKNORMAL_ROUTINE
* NormalRoutine
,
48 PVOID
* SystemArgument1
,
49 PVOID
* SystemArguemnt2
);
51 PiSuspendThreadNormalRoutine(PVOID NormalContext
,
52 PVOID SystemArgument1
,
53 PVOID SystemArgument2
);
55 /* GLOBALS *******************************************************************/
57 #define TAG_THREAD_STACK TAG('T', 'S', 'T', 'K')
59 /* FUNCTIONS *****************************************************************/
62 HalReleaseTask(PETHREAD Thread
)
64 * FUNCTION: Releases the resource allocated for a thread by
65 * HalInitTaskWithContext or HalInitTask
66 * NOTE: The thread had better not be running when this is called
69 extern unsigned int init_stack
;
71 if (Thread
->Tcb
.StackLimit
!= (ULONG
)&init_stack
)
73 ExFreePool((PVOID
)Thread
->Tcb
.StackLimit
);
75 Thread
->Tcb
.StackLimit
= 0;
76 Thread
->Tcb
.InitialStack
= NULL
;
77 Thread
->Tcb
.StackBase
= NULL
;
78 Thread
->Tcb
.KernelStack
= NULL
;
79 return(STATUS_SUCCESS
);
83 KeInitializeThread(PKPROCESS Process
, PKTHREAD Thread
, BOOLEAN First
)
85 * FUNCTION: Initialize the microkernel state of the thread
89 extern unsigned int init_stack_top
;
90 extern unsigned int init_stack
;
92 KeInitializeDispatcherHeader(&Thread
->DispatcherHeader
,
96 InitializeListHead(&Thread
->MutantListHead
);
99 KernelStack
= ExAllocatePoolWithTag(NonPagedPool
, MM_STACK_SIZE
,
101 Thread
->InitialStack
= KernelStack
+ MM_STACK_SIZE
;
102 Thread
->StackBase
= KernelStack
+ MM_STACK_SIZE
;
103 Thread
->StackLimit
= (ULONG
)KernelStack
;
104 Thread
->KernelStack
= KernelStack
+ MM_STACK_SIZE
;
108 Thread
->InitialStack
= (PVOID
)&init_stack_top
;
109 Thread
->StackBase
= (PVOID
)&init_stack_top
;
110 Thread
->StackLimit
= (ULONG
)&init_stack
;
111 Thread
->KernelStack
= (PVOID
)&init_stack_top
;
114 * The Native API function will initialize the TEB field later
117 Thread
->TlsArray
= NULL
;
118 Thread
->DebugActive
= 0;
119 Thread
->State
= THREAD_STATE_BLOCKED
;
120 Thread
->Alerted
[0] = 0;
121 Thread
->Alerted
[1] = 0;
124 * FIXME: Think how this might work
126 Thread
->NpxState
= 0;
127 Thread
->Saturation
= 0;
128 Thread
->Priority
= 0;
129 InitializeListHead(&Thread
->ApcState
.ApcListHead
[0]);
130 InitializeListHead(&Thread
->ApcState
.ApcListHead
[1]);
131 Thread
->ApcState
.Process
= Process
;
132 Thread
->ApcState
.KernelApcInProgress
= 0;
133 Thread
->ApcState
.KernelApcPending
= 0;
134 Thread
->ApcState
.UserApcPending
= 0;
135 Thread
->ContextSwitches
= 0;
136 Thread
->WaitStatus
= STATUS_SUCCESS
;
137 Thread
->WaitIrql
= 0;
138 Thread
->WaitMode
= 0;
139 Thread
->WaitNext
= 0;
140 Thread
->WaitBlockList
= NULL
;
141 Thread
->WaitListEntry
.Flink
= NULL
;
142 Thread
->WaitListEntry
.Blink
= NULL
;
143 Thread
->WaitTime
= 0;
144 Thread
->BasePriority
= 0;
145 Thread
->DecrementCount
= 0;
146 Thread
->PriorityDecrement
= 0;
148 memset(Thread
->WaitBlock
, 0, sizeof(KWAIT_BLOCK
)*4);
149 Thread
->LegoData
= 0;
153 Thread
->KernelApcDisable
= 1;
154 Thread
->UserAffinity
= 0;
155 Thread
->SystemAffinityActive
= 0;
156 Thread
->Queue
= NULL
;
157 KeInitializeSpinLock(&Thread
->ApcQueueLock
);
158 memset(&Thread
->Timer
, 0, sizeof(KTIMER
));
159 Thread
->QueueListEntry
.Flink
= NULL
;
160 Thread
->QueueListEntry
.Blink
= NULL
;
161 Thread
->Affinity
= 0;
162 Thread
->Preempted
= 0;
163 Thread
->ProcessReadyQueue
= 0;
164 Thread
->KernelStackResident
= 1;
165 Thread
->NextProcessor
= 0;
166 Thread
->CallbackStack
= NULL
;
167 Thread
->Win32Thread
= 0;
168 Thread
->TrapFrame
= NULL
;
169 Thread
->ApcStatePointer
[0] = NULL
;
170 Thread
->ApcStatePointer
[1] = NULL
;
171 Thread
->EnableStackSwap
= 0;
172 Thread
->LargeStack
= 0;
173 Thread
->ResourceIndex
= 0;
174 Thread
->PreviousMode
= KernelMode
;
175 Thread
->KernelTime
= 0;
176 Thread
->UserTime
= 0;
177 memset(&Thread
->SavedApcState
, 0, sizeof(KAPC_STATE
));
178 Thread
->Alertable
= 1;
179 Thread
->ApcStateIndex
= 0;
180 Thread
->ApcQueueable
= 0;
181 Thread
->AutoAlignment
= 0;
182 Thread
->StackBase
= KernelStack
;
183 KeInitializeApc(&Thread
->SuspendApc
,
186 PiSuspendThreadKernelRoutine
,
187 PiSuspendThreadRundownRoutine
,
188 PiSuspendThreadNormalRoutine
,
191 KeInitializeSemaphore(&Thread
->SuspendSemaphore
, 0, 255);
192 Thread
->ThreadListEntry
.Flink
= NULL
;
193 Thread
->ThreadListEntry
.Blink
= NULL
;
194 Thread
->FreezeCount
= 0;
195 Thread
->SuspendCount
= 0;
198 * Initialize ReactOS specific members
200 Thread
->ProcessThreadListEntry
.Flink
= NULL
;
201 Thread
->ProcessThreadListEntry
.Blink
= NULL
;
202 KeInitializeDpc(&Thread
->TimerDpc
, (PKDEFERRED_ROUTINE
)PiTimeoutThread
,
207 * Do x86 specific part