weiden@svn.reactos.com wrote:
Alex Ionescu ionucu@videotron.ca
- Removed ke/alert.c and moved its functions where they belong.
- Commented and organized KeInitializeThread.
- Began switch to true KOBJECT enumeration used in NT.
- Implemented KeAlertResumeThread and NtAlertResumeThread.
- Harmonized Formatting in ke/kthread.c
Modified: trunk/reactos/drivers/storage/floppy/floppy.c Modified: trunk/reactos/include/ddk/ketypes.h Modified: trunk/reactos/ntoskrnl/Makefile Modified: trunk/reactos/ntoskrnl/include/internal/ps.h
Deleted: trunk/reactos/ntoskrnl/ke/alert.c
Modified: trunk/reactos/ntoskrnl/ke/apc.c Modified: trunk/reactos/ntoskrnl/ke/dpc.c Modified: trunk/reactos/ntoskrnl/ke/kthread.c Modified: trunk/reactos/ntoskrnl/ke/wait.c Modified: trunk/reactos/ntoskrnl/ps/thread.c
What didn't fit:
Index: ntoskrnl/ke/kthread.c =================================================================== --- ntoskrnl/ke/kthread.c (.../trunk/reactos) (revision 13937) +++ ntoskrnl/ke/kthread.c (.../branches/alex_devel_branch/reactos) (revision 13942) @@ -355,20 +471,26 @@ */ CCHAR STDCALL -KeSetIdealProcessorThread ( - IN PKTHREAD Thread, - IN CCHAR Processor) +KeSetIdealProcessorThread(IN PKTHREAD Thread, + IN CCHAR Processor) { - CCHAR PreviousIdealProcessor; + CCHAR PreviousIdealProcessor; + KIRQL OldIrql; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock();
- /* Save Old Ideal Processor */ - PreviousIdealProcessor = Thread->IdealProcessor; - - /* Set New Ideal Processor */ - Thread->IdealProcessor = Processor; - - /* Return Old Ideal Processor */ - return PreviousIdealProcessor; + /* Save Old Ideal Processor */ + PreviousIdealProcessor = Thread->IdealProcessor; + + /* Set New Ideal Processor */ + Thread->IdealProcessor = Processor; + + /* Release Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return Old Ideal Processor */ + return PreviousIdealProcessor; }
/* @@ -378,86 +500,237 @@ STDCALL KeSetSystemAffinityThread(IN KAFFINITY Affinity) { -#ifdef CONFIG_SMP - PKTHREAD CurrentThread; - KIRQL oldIrql; + PKTHREAD CurrentThread = KeGetCurrentThread(); + KIRQL OldIrql;
- oldIrql = KeAcquireDispatcherDatabaseLock(); + ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock();
- CurrentThread = KeGetCurrentThread(); + /* Set the System Affinity Specified */ + CurrentThread->Affinity = Affinity;
- ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); - - /* Set the System Affinity Specified */ - CurrentThread->Affinity = Affinity; - - /* Enable System Affinity */ - CurrentThread->SystemAffinityActive = TRUE; - - if (Affinity & (1 << KeGetCurrentProcessorNumber())) - { - KeReleaseDispatcherDatabaseLock(oldIrql); - } - else - { - CurrentThread->WaitIrql = oldIrql; - PsDispatchThreadNoLock(THREAD_STATE_READY); - KeLowerIrql(oldIrql); - } -#endif + /* Enable System Affinity */ + CurrentThread->SystemAffinityActive = TRUE; + + /* Check if we need to Dispatch a New thread */ + if (Affinity & (1 << KeGetCurrentProcessorNumber())) { + + /* No, just release */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + } else { + + /* We need to dispatch a new thread */ + CurrentThread->WaitIrql = OldIrql; + PsDispatchThreadNoLock(THREAD_STATE_READY); + KeLowerIrql(OldIrql); + } }
/* * @implemented */ + /* The Increment Argument seems to be ignored by NT and always 0 when called */ VOID STDCALL KeTerminateThread(IN KPRIORITY Increment) { - /* The Increment Argument seems to be ignored by NT and always 0 when called */ - - /* Call our own internal routine */ - PsTerminateCurrentThread(0); + /* Call our own internal routine */ + PsTerminateCurrentThread(0); }
+/* + * FUNCTION: Tests whether there are any pending APCs for the current thread + * and if so the APCs will be delivered on exit from kernel mode + */ +BOOLEAN +STDCALL +KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) +{ + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); + BOOLEAN OldState; + + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database and the APC Queue */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + KiAcquireSpinLock(&Thread->ApcQueueLock); + + /* Save the old State */ + OldState = Thread->Alerted[AlertMode]; + + /* If the Thread is Alerted, Clear it */ + if (OldState) { + + Thread->Alerted[AlertMode] = FALSE; + + } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { + + /* If the mode is User and the Queue isn't empty, set Pending */ + Thread->ApcState.UserApcPending = TRUE; + } + + /* Release Locks and return the Old State */ + KiReleaseSpinLock(&Thread->ApcQueueLock); + KeReleaseDispatcherDatabaseLock(OldIrql); + return OldState; +}
+VOID +KiServiceCheck (VOID) +{ + PKTHREAD Thread = KeGetCurrentThread(); + + /* Check if we need to inialize Win32 for this Thread */ + if (Thread->ServiceTable != KeServiceDescriptorTableShadow) { + + /* We do. Initialize it and save the new table */ + PsInitWin32Thread((PETHREAD)Thread); + Thread->ServiceTable = KeServiceDescriptorTableShadow; + } +} + +/* + * + * NOT EXPORTED + */ NTSTATUS STDCALL +NtAlertResumeThread(IN HANDLE ThreadHandle, + OUT PULONG SuspendCount) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PETHREAD Thread; + NTSTATUS Status; + ULONG PreviousState; + + /* Check if parameters are valid */ + if(PreviousMode != KernelMode) { + + _SEH_TRY { + + ProbeForWrite(SuspendCount, + sizeof(HANDLE), + sizeof(ULONG)); + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + + } _SEH_END; + } + + /* Reference the Object */ + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SUSPEND_RESUME, + PsThreadType, + PreviousMode, + (PVOID*)&Thread, + NULL); + + /* Check for Success */ + if (NT_SUCCESS(Status)) { + + /* Call the Kernel Function */ + PreviousState = KeAlertResumeThread(&Thread->Tcb); + + /* Dereference Object */ + ObDereferenceObject(Thread); + + if (SuspendCount) { + + _SEH_TRY { + + *SuspendCount = PreviousState; + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + + } _SEH_END; + } + } + + /* Return status */ + return Status; +} + +/* + * @implemented + * + * EXPORTED + */ +NTSTATUS +STDCALL +NtAlertThread (IN HANDLE ThreadHandle) +{ + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + PETHREAD Thread; + NTSTATUS Status; + + /* Reference the Object */ + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_SUSPEND_RESUME, + PsThreadType, + PreviousMode, + (PVOID*)&Thread, + NULL); + + /* Check for Success */ + if (NT_SUCCESS(Status)) { + + /* + * Do an alert depending on the processor mode. If some kmode code wants to + * enforce a umode alert it should call KeAlertThread() directly. If kmode + * code wants to do a kmode alert it's sufficient to call it with Zw or just + * use KeAlertThread() directly + */ + KeAlertThread(&Thread->Tcb, PreviousMode); + + /* Dereference Object */ + ObDereferenceObject(Thread); + } + + /* Return status */ + return Status; +} + +NTSTATUS +STDCALL NtDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER DelayInterval) { - KPROCESSOR_MODE PreviousMode; - LARGE_INTEGER SafeInterval; + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + LARGE_INTEGER SafeInterval; + NTSTATUS Status;
- PreviousMode = ExGetPreviousMode(); - - if(PreviousMode != KernelMode) - { - NTSTATUS Status = STATUS_SUCCESS; + /* Check if parameters are valid */ + if(PreviousMode != KernelMode) {
- _SEH_TRY - { - ProbeForRead(DelayInterval, - sizeof(LARGE_INTEGER), - sizeof(ULONG)); - /* make a copy on the kernel stack and let DelayInterval point to it so - we don't need to wrap KeDelayExecutionThread in SEH! */ - SafeInterval = *DelayInterval; - DelayInterval = &SafeInterval; - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - - if(!NT_SUCCESS(Status)) - { - return Status; - } + _SEH_TRY { + + ProbeForRead(DelayInterval, + sizeof(LARGE_INTEGER), + sizeof(ULONG)); + + /* make a copy on the kernel stack and let DelayInterval point to it so + we don't need to wrap KeDelayExecutionThread in SEH! */ + SafeInterval = *DelayInterval; + + } _SEH_HANDLE { + + Status = _SEH_GetExceptionCode(); + } _SEH_END; }
- return KeDelayExecutionThread(PreviousMode, - Alertable, - DelayInterval); + /* Call the Kernel Function */ + Status = KeDelayExecutionThread(PreviousMode, + Alertable, + &SafeInterval); + + /* Return Status */ + return Status; } Index: ntoskrnl/ke/alert.c =================================================================== --- ntoskrnl/ke/alert.c (.../trunk/reactos) (revision 13937) +++ ntoskrnl/ke/alert.c (.../branches/alex_devel_branch/reactos) (revision 13942) @@ -1,150 +0,0 @@ -/* $Id:$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/alert.c - * PURPOSE: Alerts - * - * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - */ - -/* INCLUDES *****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <internal/debug.h> - -/* GLOBALS *******************************************************************/ - - -/* FUNCTIONS *****************************************************************/ - - -BOOLEAN -STDCALL -KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) -/* - * FUNCTION: Tests whether there are any pending APCs for the current thread - * and if so the APCs will be delivered on exit from kernel mode - */ -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN OldState; - - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); - - OldState = Thread->Alerted[AlertMode]; - - /* If the Thread is Alerted, Clear it */ - if (OldState) { - Thread->Alerted[AlertMode] = FALSE; - } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { - /* If the mode is User and the Queue isn't empty, set Pending */ - Thread->ApcState.UserApcPending = TRUE; - } - - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); - return OldState; -} - - -VOID -KeAlertThread(PKTHREAD Thread, KPROCESSOR_MODE AlertMode) -{ - KIRQL oldIrql; - - - oldIrql = KeAcquireDispatcherDatabaseLock(); - - - /* Return if thread is already alerted. */ - if (Thread->Alerted[AlertMode] == FALSE) - { - if (Thread->State == THREAD_STATE_BLOCKED && - (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && - Thread->Alertable) - { - KiAbortWaitThread(Thread, STATUS_ALERTED); - } - else - { - Thread->Alerted[AlertMode] = TRUE; - } - } - - KeReleaseDispatcherDatabaseLock(oldIrql); - -} - - -/* - * - * NOT EXPORTED - */ -NTSTATUS STDCALL -NtAlertResumeThread(IN HANDLE ThreadHandle, - OUT PULONG SuspendCount) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); - -} - -/* - * @implemented - * - * EXPORTED - */ -NTSTATUS STDCALL -NtAlertThread (IN HANDLE ThreadHandle) -{ - KPROCESSOR_MODE PreviousMode; - PETHREAD Thread; - NTSTATUS Status; - - PreviousMode = ExGetPreviousMode(); - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - PreviousMode, - (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* do an alert depending on the processor mode. If some kmode code wants to - enforce a umode alert it should call KeAlertThread() directly. If kmode - code wants to do a kmode alert it's sufficient to call it with Zw or just - use KeAlertThread() directly */ - - KeAlertThread(&Thread->Tcb, PreviousMode); - - ObDereferenceObject(Thread); - return(STATUS_SUCCESS); -} - - -/* - * NOT EXPORTED - */ -NTSTATUS -STDCALL -NtTestAlert(VOID) -{ - KPROCESSOR_MODE PreviousMode; - - PreviousMode = ExGetPreviousMode(); - - /* Check and Alert Thread if needed */ - - return KeTestAlertThread(PreviousMode) ? STATUS_ALERTED : STATUS_SUCCESS; -} -