Modified: trunk/reactos/ntoskrnl/Makefile
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/ex/timer.c
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h
Modified: trunk/reactos/ntoskrnl/include/internal/port.h
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Modified: trunk/reactos/ntoskrnl/ke/apc.c
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
Modified: trunk/reactos/ntoskrnl/ke/i386/tskswitch.S
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ke/main.c
Modified: trunk/reactos/ntoskrnl/ke/process.c
Modified: trunk/reactos/ntoskrnl/ke/queue.c
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ob/handle.c
Modified: trunk/reactos/ntoskrnl/ps/cid.c
Modified: trunk/reactos/ntoskrnl/ps/create.c
Modified: trunk/reactos/ntoskrnl/ps/debug.c
Modified: trunk/reactos/ntoskrnl/ps/idle.c
Modified: trunk/reactos/ntoskrnl/ps/kill.c
Modified: trunk/reactos/ntoskrnl/ps/process.c
Modified: trunk/reactos/ntoskrnl/ps/psmgr.c
Added: trunk/reactos/ntoskrnl/ps/query.c
Added: trunk/reactos/ntoskrnl/ps/security.c
Modified: trunk/reactos/ntoskrnl/ps/suspend.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c
Deleted: trunk/reactos/ntoskrnl/ps/tinfo.c
--- trunk/reactos/ntoskrnl/Makefile 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/Makefile 2005-03-18 05:53:04 UTC (rev 14174)
@@ -226,9 +226,10 @@
ps/locale.o \
ps/process.o \
ps/psmgr.o \
+ ps/query.o \
+ ps/security.o \
ps/suspend.o \
ps/thread.o \
- ps/tinfo.o \
ps/win32.o \
ps/w32call.o
--- trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -2003,7 +2003,35 @@
return(STATUS_NOT_IMPLEMENTED);
}
+#if 0
+NTSTATUS STDCALL
+NtNotifyChangeKey (IN HANDLE KeyHandle,
+ IN HANDLE Event,
+ IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+ IN PVOID ApcContext OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN ULONG CompletionFilter,
+ IN BOOLEAN WatchSubtree,
+ OUT PVOID Buffer,
+ IN ULONG Length,
+ IN BOOLEAN Asynchronous)
+{
+ return NtNotifyChangeMultipleKeys(KeyHandle,
+ 0,
+ NULL,
+ Event,
+ ApcRoutine,
+ ApcContext,
+ IoStatusBlock,
+ CompletionFilter,
+ WatchTree,
+ Buffer,
+ Length,
+ Asynchronous);
+}
+#endif
+
NTSTATUS STDCALL
NtQueryMultipleValueKey (IN HANDLE KeyHandle,
IN OUT PKEY_VALUE_ENTRY ValueList,
--- trunk/reactos/ntoskrnl/ex/timer.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ex/timer.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -55,6 +55,66 @@
VOID
STDCALL
+ExTimerRundown(VOID)
+{
+ PETHREAD Thread = PsGetCurrentThread();
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ BOOLEAN KillTimer = FALSE;
+ PETIMER Timer;
+
+ /* Lock the Thread's Active Timer List*/
+ KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
+
+ /* Loop through all the timers */
+ CurrentEntry = Thread->ActiveTimerListHead.Flink;
+ while (CurrentEntry != &Thread->ActiveTimerListHead) {
+
+ /* Get the Timer */
+ Timer = CONTAINING_RECORD(CurrentEntry, ETIMER, ActiveTimerListEntry);
+ DPRINT("Timer, ThreadList: %x, %x\n", Timer, Thread);
+
+ /* Unlock the list */
+ KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
+
+ /* Lock the Timer */
+ KeAcquireSpinLock(&Timer->Lock, &OldIrql);
+
+ /* Relock the active list */
+ KeAcquireSpinLockAtDpcLevel(&Thread->ActiveTimerListLock);
+
+ /* Make sure it's associated to us */
+ if ((Timer->ApcAssociated) && (&Thread->Tcb == Timer->TimerApc.Thread)) {
+
+ /* Remove it */
+ DPRINT("Removing from Thread: %x\n", Thread);
+ RemoveEntryList(&Thread->ActiveTimerListHead);
+ KeCancelTimer(&Timer->KeTimer);
+ KeRemoveQueueDpc(&Timer->TimerDpc);
+ KeRemoveQueueApc(&Timer->TimerApc);
+ Timer->ApcAssociated = FALSE;
+ KillTimer = TRUE;
+ }
+
+ /* Unlock the list */
+ KeReleaseSpinLockFromDpcLevel(&Thread->ActiveTimerListLock);
+
+ /* Unlock the Timer */
+ KeReleaseSpinLock(&Timer->Lock, OldIrql);
+
+ /* Dereference it, if needed */
+ if (KillTimer) ObDereferenceObject(Timer);
+
+ /* Loop again */
+ KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
+}
+
+VOID
+STDCALL
ExpDeleteTimer(PVOID ObjectBody)
{
KIRQL OldIrql;
--- trunk/reactos/ntoskrnl/include/internal/ex.h 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/include/internal/ex.h 2005-03-18 05:53:04 UTC (rev 14174)
@@ -185,6 +185,10 @@
NTSTATUS
ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId);
+VOID
+STDCALL
+ExTimerRundown(VOID);
+
#define InterlockedDecrementUL(Addend) \
(ULONG)InterlockedDecrement((PLONG)(Addend))
--- trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-18 05:53:04 UTC (rev 14174)
@@ -49,6 +49,35 @@
#define IPI_REQUEST_DPC 2
#define IPI_REQUEST_FREEZE 3
+/* threadsch.c ********************************************************************/
+
+/* Thread Scheduler Functions */
+
+/* Readies a Thread for Execution. */
+VOID
+STDCALL
+KiDispatchThreadNoLock(ULONG NewThreadStatus);
+
+/* Readies a Thread for Execution. */
+VOID
+STDCALL
+KiDispatchThread(ULONG NewThreadStatus);
+
+/* Puts a Thread into a block state. */
+VOID
+STDCALL
+KiBlockThread(PNTSTATUS Status,
+ UCHAR Alertable,
+ ULONG WaitMode,
+ UCHAR WaitReason);
+
+/* Removes a thread out of a block state. */
+VOID
+STDCALL
+KiUnblockThread(PKTHREAD Thread,
+ PNTSTATUS WaitStatus,
+ KPRIORITY Increment);
+
/* ipi.c ********************************************************************/
BOOLEAN STDCALL
@@ -150,6 +179,29 @@
VOID inline FASTCALL KeReleaseDispatcherDatabaseLock(KIRQL Irql);
VOID inline FASTCALL KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
+VOID
+STDCALL
+KeInitializeThread(struct _KPROCESS* Process, PKTHREAD Thread, BOOLEAN First);
+
+VOID
+STDCALL
+KeRundownThread(VOID);
+
+NTSTATUS KeReleaseThread(PKTHREAD Thread);
+
+VOID
+STDCALL
+KeStackAttachProcess (
+ IN struct _KPROCESS* Process,
+ OUT PKAPC_STATE ApcState
+ );
+
+VOID
+STDCALL
+KeUnstackDetachProcess (
+ IN PKAPC_STATE ApcState
+ );
+
BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment);
VOID STDCALL KeExpireTimers(PKDPC Apc,
PVOID Arg1,
@@ -165,6 +217,10 @@
KiAbortWaitThread(PKTHREAD Thread,
NTSTATUS WaitStatus,
KPRIORITY Increment);
+
+ULONG
+STDCALL
+KeForceResumeThread(IN PKTHREAD Thread);
BOOLEAN STDCALL KiInsertTimer(PKTIMER Timer, LARGE_INTEGER DueTime);
@@ -182,6 +238,18 @@
PVOID Reserved,
PKTRAP_FRAME TrapFrame);
+LONG
+STDCALL
+KiInsertQueue(IN PKQUEUE Queue,
+ IN PLIST_ENTRY Entry,
+ BOOLEAN Head);
+
+ULONG
+STDCALL
+KeSetProcess(struct _KPROCESS* Process,
+ KPRIORITY Increment);
+
+
VOID STDCALL KeInitializeEventPair(PKEVENT_PAIR EventPair);
VOID STDCALL KiInitializeUserApc(IN PVOID Reserved,
--- trunk/reactos/ntoskrnl/include/internal/ob.h 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/include/internal/ob.h 2005-03-18 05:53:04 UTC (rev 14174)
@@ -302,7 +302,9 @@
VOID FASTCALL
ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent);
-
+VOID
+STDCALL
+ObKillProcess(PEPROCESS Process);
/* Security descriptor cache functions */
NTSTATUS
--- trunk/reactos/ntoskrnl/include/internal/port.h 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/include/internal/port.h 2005-03-18 05:53:04 UTC (rev 14174)
@@ -29,14 +29,6 @@
ULONG MaxPoolUsage; /* size of NP zone */
} EPORT, * PEPORT;
-
-typedef struct _EPORT_TERMINATION_REQUEST
-{
- LIST_ENTRY ThreadListEntry;
- PEPORT Port;
-} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
-
-
typedef struct _EPORT_CONNECT_REQUEST_MESSAGE
{
LPC_MESSAGE MessageHeader;
@@ -59,6 +51,11 @@
UCHAR ConnectData[0];
} EPORT_CONNECT_REPLY_MESSAGE, *PEPORT_CONNECT_REPLY_MESSAGE;
+typedef struct _TERMINATION_PORT {
+ LIST_ENTRY Links;
+ PVOID Port;
+} TERMINATION_PORT, *PTERMINATION_PORT;
+
NTSTATUS STDCALL
LpcRequestPort (PEPORT Port,
PLPC_MESSAGE LpcMessage);
--- trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-18 05:53:04 UTC (rev 14174)
@@ -201,6 +201,7 @@
UCHAR ActiveImpersonationInfo;
ULONG PerformanceCountHigh;
LIST_ENTRY ThreadListEntry;
+ BOOLEAN SystemThread;
} ETHREAD;
#include <poppack.h>
@@ -437,7 +438,6 @@
VOID PsInitThreadManagment(VOID);
VOID PsInitProcessManagment(VOID);
VOID PsInitIdleThread(VOID);
-VOID PsDispatchThreadNoLock(ULONG NewThreadStatus);
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus);
@@ -458,17 +458,23 @@
KPROCESSOR_MODE AccessMode,
BOOLEAN First);
-PACCESS_TOKEN PsReferenceEffectiveToken(PETHREAD Thread,
+PACCESS_TOKEN STDCALL PsReferenceEffectiveToken(PETHREAD Thread,
PTOKEN_TYPE TokenType,
PUCHAR b,
PSECURITY_IMPERSONATION_LEVEL Level);
-NTSTATUS PsOpenTokenOfProcess(HANDLE ProcessHandle,
+NTSTATUS STDCALL PsOpenTokenOfProcess(HANDLE ProcessHandle,
PACCESS_TOKEN* Token);
-
+VOID
+STDCALL
+PspTerminateProcessThreads(PEPROCESS Process,
+ NTSTATUS ExitStatus);
NTSTATUS PsSuspendThread(PETHREAD Thread, PULONG PreviousCount);
NTSTATUS PsResumeThread(PETHREAD Thread, PULONG PreviousCount);
-
+NTSTATUS
+STDCALL
+PspAssignPrimaryToken(PEPROCESS Process,
+ HANDLE TokenHandle);
VOID STDCALL PsExitSpecialApc(PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
PVOID *NormalContext,
@@ -497,27 +503,25 @@
#define PROCESS_PRIO_RT 18
-VOID STDCALL
-KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
-NTSTATUS KeReleaseThread(PKTHREAD Thread);
+VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
+VOID
+STDCALL
+PspReapRoutine(PVOID Context);
+
VOID
STDCALL
-KeStackAttachProcess (
- IN PKPROCESS Process,
- OUT PKAPC_STATE ApcState
- );
+PspExitThread(NTSTATUS ExitStatus);
+extern LIST_ENTRY PspReaperListHead;
+extern WORK_QUEUE_ITEM PspReaperWorkItem;
+extern BOOLEAN PspReaping;
+
VOID
STDCALL
-KeUnstackDetachProcess (
- IN PKAPC_STATE ApcState
- );
+PspTerminateThreadByPointer(PETHREAD Thread,
+ NTSTATUS ExitStatus);
-VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
-VOID PsReapThreads(VOID);
-VOID PsInitializeThreadReaper(VOID);
-VOID PsQueueThreadReap(PETHREAD Thread);
VOID PsUnfreezeOtherThread(PETHREAD Thread);
VOID PsFreezeOtherThread(PETHREAD Thread);
VOID PsFreezeProcessThreads(PEPROCESS Process);
@@ -525,19 +529,9 @@
ULONG PsEnumThreadsByProcess(PEPROCESS Process);
PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
VOID
-STDCALL
-PsBlockThread(PNTSTATUS Status,
- UCHAR Alertable,
- ULONG WaitMode,
- UCHAR WaitReason);
-VOID
-PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment);
-VOID
PsApplicationProcessorInit(VOID);
VOID
PsPrepareForApplicationProcessorInit(ULONG Id);
-VOID
-PsInitReaperThread(VOID);
VOID STDCALL
PsIdleThreadMain(PVOID Context);
@@ -553,11 +547,20 @@
PiSuspendThreadNormalRoutine(PVOID NormalContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
-VOID STDCALL
-PsDispatchThread(ULONG NewThreadStatus);
VOID
PsInitialiseSuspendImplementation(VOID);
+NTSTATUS
+STDCALL
+PspExitProcess(PEPROCESS Process);
+VOID
+STDCALL
+PspDeleteProcess(PVOID ObjectBody);
+
+VOID
+STDCALL
+PspDeleteThread(PVOID ObjectBody);
+
extern LONG PiNrThreadsAwaitingReaping;
NTSTATUS
--- trunk/reactos/ntoskrnl/ke/apc.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ke/apc.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -14,10 +14,6 @@
#define NDEBUG
#include <internal/debug.h>
-/* GLOBALS *******************************************************************/
-
-VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
-
/* FUNCTIONS *****************************************************************/
/*++
@@ -145,19 +141,15 @@
}
/*++
- * KeInsertQueueApc
- * @implemented NT4
+ * KiInsertQueueApc
*
- * The KeInsertQueueApc routine queues a APC for execution when the right
+ * The KiInsertQueueApc routine queues a APC for execution when the right
* scheduler environment exists.
*
* Params:
* Apc - Pointer to an initialized control object of type DPC for which the
* caller provides the storage.
*
- * SystemArgument[1,2] - Pointer to a set of two parameters that contain
- * untyped data.
- *
* PriorityBoost - Priority Boost to apply to the Thread.
*
* Returns:
@@ -173,45 +165,16 @@
*--*/
BOOLEAN
STDCALL
-KeInsertQueueApc(PKAPC Apc,
- PVOID SystemArgument1,
- PVOID SystemArgument2,
+KiInsertQueueApc(PKAPC Apc,
KPRIORITY PriorityBoost)
-
{
- KIRQL OldIrql;
- PKTHREAD Thread;
+ PKTHREAD Thread = Apc->Thread;
PLIST_ENTRY ApcListEntry;
PKAPC QueuedApc;
-
- ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
- DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
- "SystemArgument2 %x)\n",Apc,SystemArgument1,
- SystemArgument2);
-
- /* Lock the Dispatcher Database */
- OldIrql = KeAcquireDispatcherDatabaseLock();
- /* Get the Thread specified in the APC */
- Thread = Apc->Thread;
-
- /* Make sure the thread allows APC Queues.
- * The thread is not apc queueable, for instance, when it's (about to be) terminated.
- */
- if (Thread->ApcQueueable == FALSE) {
- DPRINT("Thread doesn't allow APC Queues\n");
- KeReleaseDispatcherDatabaseLock(OldIrql);
- return FALSE;
- }
-
- /* Set the System Arguments */
- Apc->SystemArgument1 = SystemArgument1;
- Apc->SystemArgument2 = SystemArgument2;
-
/* Don't do anything if the APC is already inserted */
if (Apc->Inserted) {
- KeReleaseDispatcherDatabaseLock(OldIrql);
return FALSE;
}
@@ -247,7 +210,7 @@
DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
- &Apc->ApcListEntry);
+ &Apc->ApcListEntry);
}
/* Confirm Insertion */
@@ -271,9 +234,9 @@
DPRINT ("Requesting APC Interrupt for Running Thread \n");
HalRequestSoftwareInterrupt(APC_LEVEL);
- } else if ((Thread->State == THREAD_STATE_BLOCKED) &&
- (Thread->WaitIrql < APC_LEVEL) &&
- (Apc->NormalRoutine == NULL)) {
+ } else if ((Thread->State == THREAD_STATE_BLOCKED) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
+ ((Apc->NormalRoutine == NULL) ||
+ ((!Thread->KernelApcDisable) && (!Thread->ApcState.KernelApcInProgress)))) {
DPRINT("Waking up Thread for Kernel-Mode APC Delivery \n");
KiAbortWaitThread(Thread, STATUS_KERNEL_APC, PriorityBoost);
@@ -287,10 +250,79 @@
Thread->ApcState.UserApcPending = TRUE;
KiAbortWaitThread(Thread, STATUS_USER_APC, PriorityBoost);
}
+
+ return TRUE;
+}
+
+/*++
+ * KeInsertQueueApc
+ * @implemented NT4
+ *
+ * The KeInsertQueueApc routine queues a APC for execution when the right
+ * scheduler environment exists.
+ *
+ * Params:
+ * Apc - Pointer to an initialized control object of type DPC for which the
+ * caller provides the storage.
+ *
+ * SystemArgument[1,2] - Pointer to a set of two parameters that contain
+ * untyped data.
+ *
+ * PriorityBoost - Priority Boost to apply to the Thread.
+ *
+ * Returns:
+ * If the APC is already inserted or APC queueing is disabled, FALSE.
+ * Otherwise, TRUE.
+ *
+ * Remarks:
+ * The APC will execute at APC_LEVEL for the KernelRoutine registered, and
+ * at PASSIVE_LEVEL for the NormalRoutine registered.
+ *
+ * Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
+BOOLEAN
+STDCALL
+KeInsertQueueApc(PKAPC Apc,
+ PVOID SystemArgument1,
+ PVOID SystemArgument2,
+ KPRIORITY PriorityBoost)
+{
+ KIRQL OldIrql;
+ PKTHREAD Thread;
+ BOOLEAN Inserted;
+
+ ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+ DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
+ "SystemArgument2 %x)\n",Apc,SystemArgument1,
+ SystemArgument2);
+
+ /* Lock the Dispatcher Database */
+ OldIrql = KeAcquireDispatcherDatabaseLock();
+
+ /* Get the Thread specified in the APC */
+ Thread = Apc->Thread;
+
+ /* Make sure the thread allows APC Queues.
+ * The thread is not apc queueable, for instance, when it's (about to be) terminated.
+ */
+ if (Thread->ApcQueueable == FALSE) {
+ DPRINT("Thread doesn't allow APC Queues\n");
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+ return FALSE;
+ }
+
+ /* Set the System Arguments */
+ Apc->SystemArgument1 = SystemArgument1;
+ Apc->SystemArgument2 = SystemArgument2;
+
+ /* Call the Internal Function */
+ Inserted = KiInsertQueueApc(Apc, PriorityBoost);
+
/* Return Sucess if we are here */
KeReleaseDispatcherDatabaseLock(OldIrql);
- return TRUE;
+ return Inserted;
}
/*++
--- trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -491,7 +491,7 @@
/* Dispatch the Thread */
KeLowerIrql(DISPATCH_LEVEL);
- PsDispatchThread(THREAD_STATE_READY);
+ KiDispatchThread(THREAD_STATE_READY);
}
/*
--- trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -582,6 +582,125 @@
}
VOID
+KeContextToTrapFrame(PCONTEXT Context,
+ PKTRAP_FRAME TrapFrame)
+{
+ if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+ {
+ TrapFrame->Esp = Context->Esp;
+ TrapFrame->Ss = Context->SegSs;
+ TrapFrame->Cs = Context->SegCs;
+ TrapFrame->Eip = Context->Eip;
+ TrapFrame->Eflags = Context->EFlags;
+ TrapFrame->Ebp = Context->Ebp;
+ }
+ if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ {
+ TrapFrame->Eax = Context->Eax;
+ TrapFrame->Ebx = Context->Ebx;
+ TrapFrame->Ecx = Context->Ecx;
+ TrapFrame->Edx = Context->Edx;
+ TrapFrame->Esi = Context->Esi;
+ TrapFrame->Edi = Context->Edi;
+ }
+ if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+ {
+ TrapFrame->Ds = Context->SegDs;
+ TrapFrame->Es = Context->SegEs;
+ TrapFrame->Fs = Context->SegFs;
+ TrapFrame->Gs = Context->SegGs;
+ }
+ if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
+ {
+ /*
+ * Not handled
+ *
+ * This should be handled separately I think.
+ * - blight
+ */
+ }
+ if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+ {
+ /*
+ * Not handled
+ */
+ }
+}
+
+VOID
+KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
+ PCONTEXT Context)
+{
+ if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+ {
+ Context->SegSs = TrapFrame->Ss;
+ Context->Esp = TrapFrame->Esp;
+ Context->SegCs = TrapFrame->Cs;
+ Context->Eip = TrapFrame->Eip;
+ Context->EFlags = TrapFrame->Eflags;
+ Context->Ebp = TrapFrame->Ebp;
+ }
+ if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ {
+ Context->Eax = TrapFrame->Eax;
+ Context->Ebx = TrapFrame->Ebx;
+ Context->Ecx = TrapFrame->Ecx;
+ /*
+ * NOTE: In the trap frame which is built on entry to a system
+ * call TrapFrame->Edx will actually hold the address of the
+ * previous TrapFrame. I don't believe leaking this information
+ * has security implications. Also EDX holds the address of the
+ * arguments to the system call in progress so it isn't of much
+ * interest to the debugger.
+ */
+ Context->Edx = TrapFrame->Edx;
+ Context->Esi = TrapFrame->Esi;
+ Context->Edi = TrapFrame->Edi;
+ }
+ if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+ {
+ Context->SegDs = TrapFrame->Ds;
+ Context->SegEs = TrapFrame->Es;
+ Context->SegFs = TrapFrame->Fs;
+ Context->SegGs = TrapFrame->Gs;
+ }
+ if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
+ {
+ /*
+ * FIXME: Implement this case
+ */
+ Context->ContextFlags &= (~CONTEXT_DEBUG_REGISTERS) | CONTEXT_i386;
+ }
+ if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
+ {
+ /*
+ * FIXME: Implement this case
+ *
+ * I think this should only be filled for FPU exceptions, otherwise I
+ * would not know where to get it from as it can be the current state
+ * of the FPU or already saved in the thread's FPU save area.
+ * -blight
+ */
+ Context->ContextFlags &= (~CONTEXT_FLOATING_POINT) | CONTEXT_i386;
+ }
+#if 0
+ if ((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS)
+ {
+ /*
+ * FIXME: Investigate this
+ *
+ * This is the XMM state (first 512 bytes of FXSAVE_FORMAT/FX_SAVE_AREA)
+ * This should only be filled in case of a SIMD exception I think, so
+ * this is not the right place (like for FPU the state could already be
+ * saved in the thread's FX_SAVE_AREA or still be in the CPU)
+ * -blight
+ */
+ Context->ContextFlags &= ~CONTEXT_EXTENDED_REGISTERS;
+ }
+#endif
+}
+
+VOID
KeDumpStackFrames(PULONG Frame)
{
PULONG StackBase, StackEnd;
--- trunk/reactos/ntoskrnl/ke/i386/tskswitch.S 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ke/i386/tskswitch.S 2005-03-18 05:53:04 UTC (rev 14174)
@@ -206,11 +206,6 @@
call @KeReleaseDispatcherDatabaseLockFromDpcLevel@0
- cmpl $0, _PiNrThreadsAwaitingReaping
- je 5f
- call _PiWakeupReaperThread@0
-5:
-
/*
* Restore the saved register and exit
*/
--- trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-18 03:26:12 UTC (rev 14173)
+++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-18 05:53:04 UTC (rev 14174)
@@ -15,10 +15,478 @@
#include <internal/debug.h>
#define THREAD_ALERT_INCREMENT 2
+
+extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
+
+/*
+ * PURPOSE: List of threads associated with each priority level
+ */
+LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
+static ULONG PriorityListMask = 0;
+ULONG IdleProcessorMask = 0;
+extern BOOLEAN DoneInitYet;
+
/* FUNCTIONS *****************************************************************/
+STATIC
+VOID
+KiRequestReschedule(CCHAR Processor)
+{
+ PKPCR Pcr;
+
+ Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE);
+ Pcr->Prcb->QuantumEnd = TRUE;
+ KiIpiSendRequest(1 << Processor, IPI_REQUEST_DPC);
+}
+
+STATIC
+VOID
+KiInsertIntoThreadList(KPRIORITY Priority,
+ PKTHREAD Thread)
+{
+ ASSERT(THREAD_STATE_READY == Thread->State);
+ ASSERT(Thread->Priority == Priority);
+
+ if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) {
+
+ DPRINT1("Invalid thread priority (%d)\n", Priority);
+ KEBUGCHECK(0);
+ }
+
+ InsertTailList(&PriorityListHead[Priority], &Thread->QueueListEntry);
+ PriorityListMask |= (1 << Priority);
+}
+
+STATIC
+VOID
+KiRemoveFromThreadList(PKTHREAD Thread)
+{
+ ASSERT(THREAD_STATE_READY == Thread->State);
+ RemoveEntryList(&Thread->QueueListEntry);
+ if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) {
+
+ PriorityListMask &= ~(1 << Thread->Priority);
+ }
+}
+
+STATIC
+PKTHREAD
+KiScanThreadList(KPRIORITY Priority,
+ KAFFINITY Affinity)
+{
+ PLIST_ENTRY current_entry;
+ PKTHREAD current;
+ ULONG Mask;
+
+ Mask = (1 << Priority);
+
+ if (PriorityListMask & Mask) {
+
+ current_entry = PriorityListHead[Priority].Flink;
+
+ while (current_entry != &PriorityListHead[Priority]) {
+
+ current = CONTAINING_RECORD(current_entry, KTHREAD, QueueListEntry);
+
+ if (current->State != THREAD_STATE_READY) {
+
+ DPRINT1("%d/%d\n", ¤t, current->State);
+ }
+
+ ASSERT(current->State == THREAD_STATE_READY);
+
+ if (current->Affinity & Affinity) {
+
+ KiRemoveFromThreadList(current);
+ return(current);
+ }
+
+ current_entry = current_entry->Flink;
+ }
+ }
+
+ return(NULL);
+}
+
+VOID
+STDCALL
+KiDispatchThreadNoLock(ULONG NewThreadStatus)
+{
+ KPRIORITY CurrentPriority;
+ PKTHREAD Candidate;
+ ULONG Affinity;
+ PKTHREAD CurrentThread = KeGetCurrentThread();
+
+ DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
+ CurrentThread, NewThreadStatus, CurrentThread->State);
+
+ CurrentThread->State = (UCHAR)NewThreadStatus;
+
+ if (NewThreadStatus == THREAD_STATE_READY) {
+
+ KiInsertIntoThreadList(CurrentThread->Priority,
+ CurrentThread);
+ }
+
+ Affinity = 1 << KeGetCurrentProcessorNumber();
+
+ for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) {
+
+ Candidate = KiScanThreadList(CurrentPriority, Affinity);
+
+ if (Candidate == CurrentThread) {
+
+ Candidate->State = THREAD_STATE_RUNNING;
+ KeReleaseDispatcherDatabaseLockFromDpcLevel();
+ return;
+ }
+
+ if (Candidate != NULL) {
+
+ PKTHREAD OldThread;
+ PKTHREAD IdleThread;
+
+ DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
+
+ Candidate->State = THREAD_STATE_RUNNING;
+
+ OldThread = CurrentThread;
+ CurrentThread = Candidate;
+ IdleThread = KeGetCurrentPrcb()->IdleThread;
+
+ if (OldThread == IdleThread) {
+
+ IdleProcessorMask &= ~Affinity;
+
+ } else if (CurrentThread == IdleThread) {
+
+ IdleProcessorMask |= Affinity;
+ }
+
+ MmUpdatePageDir(PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS));
+
+ /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
+ KiArchContextSwitch(CurrentThread, OldThread);
+ return;
+ }
+ }
+
+ DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
+ KEBUGCHECK(0);
+}
+
+VOID
+STDCALL
+KiBlockThread(PNTSTATUS Status,
+ UCHAR Alertable,
+ ULONG WaitMode,
+ UCHAR WaitReason)
+{
+ PKTHREAD Thread = KeGetCurrentThread();
+ PKWAIT_BLOCK WaitBlock;
+
+ if (Thread->ApcState.KernelApcPending) {
+
+ DPRINT("Dispatching Thread as ready (APC!)\n");
+
+ /* Remove Waits */
+ WaitBlock = Thread->WaitBlockList;
+ while (WaitBlock) {
+ RemoveEntryList (&WaitBlock->WaitListEntry);
+ WaitBlock = WaitBlock->NextWaitBlock;
+ }
+ Thread->WaitBlockList = NULL;
+
+ /* Dispatch it and return status */
+ KiDispatchThreadNoLock (THREAD_STATE_READY);
+ if (Status != NULL) *Status = STATUS_KERNEL_APC;
+
+ } else {
+
+ /* Set the Thread Data as Requested */
+ DPRINT("Dispatching Thread as blocked\n");
+ Thread->Alertable = Alertable;
+ Thread->WaitMode = (UCHAR)WaitMode;
+ Thread->WaitReason = WaitReason;
+
+ /* Dispatch it and return status */
+ KiDispatchThreadNoLock(THREAD_STATE_BLOCKED);
+ if (Status != NULL) *Status = Thread->WaitStatus;
+ }
+
+ DPRINT("Releasing Dispatcher Lock\n");
+ KfLowerIrql(Thread->WaitIrql);
+}
+
+VOID
+STDCALL
+KiDispatchThread(ULONG NewThreadStatus)
+{
+ KIRQL OldIrql;
+
+ if (!DoneInitYet || KeGetCurrentPrcb()->IdleThread == NULL) {
+ return;
+ }
+
+ OldIrql = KeAcquireDispatcherDatabaseLock();
+ KiDispatchThreadNoLock(NewThreadStatus);
+ KeLowerIrql(OldIrql);
+}
+
+VOID
+STDCALL
+KiUnblockThread(PKTHREAD Thread,
+ PNTSTATUS WaitStatus,
+ KPRIORITY Increment)
+{
+ if (THREAD_STATE_TERMINATED_1 == Thread->State ||
+ THREAD_STATE_TERMINATED_2 == Thread->State) {
[truncated at 1000 lines; 7432 more skipped]