test: ke.h File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# ke.h File Reference

Go to the source code of this file.

## Classes

struct | _KTHREAD_SWITCH_COUNTERS
struct | _KAPC_STATE
struct | _DISPATCHER_HEADER
struct | _KWAIT_BLOCK
struct | _KSERVICE_TABLE_DESCRIPTOR
struct | _KDEVICE_QUEUE
struct | _KDEVICE_QUEUE_ENTRY
struct | _KEVENT
struct | _KEVENT_PAIR
struct | _KINTERRUPT
struct | _KMUTANT
struct | _KQUEUE
struct | _KSEMAPHORE
struct | _KTIMER
struct | _KTHREAD
struct | _KPROCESS
struct | _KPROFILE
struct | _ECHANNEL
struct | _KBUGCHECK_CALLBACK_RECORD

## Defines

#define | CLOCK_QUANTUM_DECREMENT 3
#define | WAIT_QUANTUM_DECREMENT 1
#define | READY_SKIP_QUANTUM 2
#define | THREAD_QUANTUM (READY_SKIP_QUANTUM * CLOCK_QUANTUM_DECREMENT)
#define | ROUND_TRIP_DECREMENT_COUNT 16
#define | BASE_PRIORITY_THRESHOLD NORMAL_BASE_PRIORITY
#define | THREAD_WAIT_OBJECTS 3
#define | EVENT_WAIT_BLOCK 2
#define | SEMAPHORE_WAIT_BLOCK 2
#define | TIMER_WAIT_BLOCK 3
#define | TIMER_TABLE_SIZE 128
#define | KeGetCurrentApcEnvironment() KeGetCurrentThread()->ApcStateIndex
#define | DISPATCHER_OBJECT_TYPE_MASK 0x7
#define | NUMBER_SERVICE_TABLES 4
#define | SERVICE_NUMBER_MASK ((1 << 12) - 1)
#define | SERVICE_TABLE_SHIFT (12 - 4)
#define | SERVICE_TABLE_MASK (((1 << 2) - 1) << 4)
#define | SERVICE_TABLE_TEST (WIN32K_SERVICE_INDEX << 4)
#define | LISTEN_CHANNEL 0x1
#define | MESSAGE_CHANNEL 0x2
#define | KeInitializeEvent(_Event, _Type, _State)
#define | KeClearEvent(Event) (Event)->Header.SignalState = 0
#define | KeSetHighEventPair(EventPair, Increment, Wait)
#define | KeSetLowEventPair(EventPair, Increment, Wait)
#define | KeReadStateMutex(Mutex) KeReadStateMutant(Mutex)
#define | KeIsAttachedProcess() (KeGetCurrentThread()->ApcStateIndex == AttachedApcEnvironment)
#define | KeTerminateProcess(Process) (Process)->StackCount += 1;
#define | KiLeaveCriticalRegion()
#define | KeEnterCriticalRegion() KeGetCurrentThread()->KernelApcDisable -= 1;
#define | KeLeaveCriticalRegion() KiLeaveCriticalRegion()
#define | KeSetHighWaitLowEventPair(EventPair, WaitMode)
#define | KeSetLowWaitHighEventPair(EventPair, WaitMode)
#define | KeWaitForHighEventPair(EventPair, WaitMode, Alertable, TimeOut)
#define | KeWaitForLowEventPair(EventPair, WaitMode, Alertable, TimeOut)
#define | KeWaitForMutexObject KeWaitForSingleObject
#define | _DECL_HAL_KE_IMPORT
#define | KiLockDispatcherDatabase(OldIrql) *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&KiDispatcherLock)
#define | KeAcquireSpinLock(SpinLock, OldIrql) *(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)
#define | KeInitializeCallbackRecord(CallbackRecord) (CallbackRecord)->State = BufferEmpty
#define | KeFindFirstSetRightMember(Set)
#define | DMA_READ_DCACHE_INVALIDATE 0x1
#define | DMA_READ_ICACHE_INVALIDATE 0x2
#define | DMA_WRITE_DCACHE_SNOOP 0x4
#define | SYSTEM_SERVICE_INDEX 0
#define | WIN32K_SERVICE_INDEX 1
#define | IIS_SERVICE_INDEX 2

## Typedefs

typedef _KTHREAD_SWITCH_COUNTERS | KTHREAD_SWITCH_COUNTERS
typedef _KTHREAD_SWITCH_COUNTERS * | PKTHREAD_SWITCH_COUNTERS
typedef enum _KOBJECTS | KOBJECTS
typedef enum _KAPC_ENVIRONMENT | KAPC_ENVIRONMENT
typedef enum _KINTERRUPT_MODE | KINTERRUPT_MODE
typedef enum _KPROCESS_STATE | KPROCESS_STATE
typedef enum _KTHREAD_STATE | KTHREAD_STATE
typedef enum _KWAIT_REASON | KWAIT_REASON
typedef _KAPC_STATE | KAPC_STATE
typedef _KAPC_STATE * | PKAPC_STATE
typedef _KAPC_STATE | PRKAPC_STATE
typedef _DISPATCHER_HEADER | DISPATCHER_HEADER
typedef ULONG | KPAGE_FRAME
typedef _KWAIT_BLOCK | KWAIT_BLOCK
typedef _KWAIT_BLOCK * | PKWAIT_BLOCK
typedef _KWAIT_BLOCK | PRKWAIT_BLOCK
typedef _KSERVICE_TABLE_DESCRIPTOR | KSERVICE_TABLE_DESCRIPTOR
typedef _KSERVICE_TABLE_DESCRIPTOR * | PKSERVICE_TABLE_DESCRIPTOR
typedef BOOLEAN(* | PKDEBUG_ROUTINE )(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)
typedef BOOLEAN(* | PKDEBUG_SWITCH_ROUTINE )(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
typedef VOID(* | PKSTART_ROUTINE )(IN PVOID StartContext)
typedef VOID(* | PKSYSTEM_ROUTINE )(IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL)
typedef _KDEVICE_QUEUE | KDEVICE_QUEUE
typedef _KDEVICE_QUEUE * | PKDEVICE_QUEUE
typedef _KDEVICE_QUEUE | PRKDEVICE_QUEUE
typedef _KDEVICE_QUEUE_ENTRY | KDEVICE_QUEUE_ENTRY
typedef _KDEVICE_QUEUE_ENTRY * | PKDEVICE_QUEUE_ENTRY
typedef _KDEVICE_QUEUE_ENTRY | PRKDEVICE_QUEUE_ENTRY
typedef _KEVENT | KEVENT
typedef _KEVENT * | PKEVENT
typedef _KEVENT | PRKEVENT
typedef _KEVENT_PAIR | KEVENT_PAIR
typedef _KEVENT_PAIR * | PKEVENT_PAIR
typedef _KEVENT_PAIR | PRKEVENT_PAIR
typedef BOOLEAN(* | PKSERVICE_ROUTINE )(IN struct _KINTERRUPT *Interrupt, IN PVOID ServiceContext)
typedef _KINTERRUPT | KINTERRUPT
typedef _KINTERRUPT * | PKINTERRUPT
typedef _KINTERRUPT *RESTRICTED_POINTER | PRKINTERRUPT
typedef _KMUTANT | KMUTANT
typedef _KMUTANT * | PKMUTANT
typedef _KMUTANT | PRKMUTANT
typedef _KMUTANT | KMUTEX
typedef _KMUTANT * | PKMUTEX
typedef _KMUTANT | PRKMUTEX
typedef _KQUEUE | KQUEUE
typedef _KQUEUE * | PKQUEUE
typedef _KQUEUE | PRKQUEUE
typedef _KSEMAPHORE | KSEMAPHORE
typedef _KSEMAPHORE * | PKSEMAPHORE
typedef _KSEMAPHORE | PRKSEMAPHORE
typedef _KTIMER | KTIMER
typedef _KTIMER * | PKTIMER
typedef _KTIMER | PRKTIMER
typedef _KTHREAD | KTHREAD
typedef _KTHREAD * | PKTHREAD
typedef _KTHREAD | PRKTHREAD
typedef _KPROCESS | KPROCESS
typedef _KPROCESS * | PKPROCESS
typedef _KPROCESS | PRKPROCESS
typedef _KPROFILE | KPROFILE
typedef _KPROFILE * | PKPROFILE
typedef _KPROFILE | PRKPROFILE
typedef enum _ECHANNEL_STATE | ECHANNEL_STATE
typedef _ECHANNEL | ECHANNEL
typedef _ECHANNEL * | PECHANNEL
typedef _ECHANNEL | PRECHANNEL
typedef enum _KBUGCHECK_BUFFER_DUMP_STATE | KBUGCHECK_BUFFER_DUMP_STATE
typedef VOID(* | PKBUGCHECK_CALLBACK_ROUTINE )(IN PVOID Buffer, IN ULONG Length)
typedef _KBUGCHECK_CALLBACK_RECORD | KBUGCHECK_CALLBACK_RECORD
typedef _KBUGCHECK_CALLBACK_RECORD * | PKBUGCHECK_CALLBACK_RECORD
typedef PCHAR(* | PKE_BUGCHECK_UNICODE_TO_ANSI )(IN PUNICODE_STRING UnicodeString, OUT PCHAR AnsiBuffer, IN ULONG MaxAnsiLength)
typedef VOID(* | PGDI_BATCHFLUSH_ROUTINE )(VOID)
typedef enum _FIRMWARE_REENTRY | FIRMWARE_REENTRY
typedef enum _FIRMWARE_REENTRY * | PFIRMWARE_REENTRY
typedef VOID(FASTCALL * | PSWAP_CONTEXT_NOTIFY_ROUTINE )(IN HANDLE OldThreadId, IN HANDLE NewThreadId)
typedef LOGICAL(FASTCALL * | PTHREAD_SELECT_NOTIFY_ROUTINE )(IN HANDLE ThreadId)
typedef VOID(FASTCALL * | PTIME_UPDATE_NOTIFY_ROUTINE )(IN HANDLE ThreadId, IN KPROCESSOR_MODE Mode)
typedef enum _MEMORY_CACHING_TYPE_ORIG | MEMORY_CACHING_TYPE_ORIG
typedef enum _MEMORY_CACHING_TYPE | MEMORY_CACHING_TYPE

## Enumerations

enum

_KOBJECTS {
EventNotificationObject = 0, EventSynchronizationObject = 1, MutantObject = 2, ProcessObject = 3,
QueueObject = 4, SemaphoreObject = 5, ThreadObject = 6, Spare1Object = 7,
TimerNotificationObject = 8, TimerSynchronizationObject = 9, Spare2Object = 10, Spare3Object = 11,
Spare4Object = 12, Spare5Object = 13, Spare6Object = 14, Spare7Object = 15,
Spare8Object = 16, Spare9Object = 17, ApcObject, DpcObject,
DeviceQueueObject, EventPairObject, InterruptObject, ProfileObject
}

enum | _KAPC_ENVIRONMENT { OriginalApcEnvironment, AttachedApcEnvironment, CurrentApcEnvironment }
enum | _KINTERRUPT_MODE { LevelSensitive, Latched }
enum | _KPROCESS_STATE { ProcessInMemory, ProcessOutOfMemory, ProcessInTransition, ProcessInSwap, ProcessOutSwap }
enum | _KTHREAD_STATE { Initialized, Ready, Running, Standby, Terminated, Waiting, Transition }

enum

_KWAIT_REASON {
Executive, FreePage, PageIn, PoolAllocation,
DelayExecution, Suspended, UserRequest, WrExecutive,
WrFreePage, WrPageIn, WrPoolAllocation, WrDelayExecution,
WrSuspended, WrUserRequest, WrEventPair, WrQueue,
WrLpcReceive, WrLpcReply, WrVirtualMemory, WrPageOut,
WrRendezvous, Spare2, Spare3, Spare4,
Spare5, Spare6, WrKernel, MaximumWaitReason
}

enum | KCONTINUE_STATUS { ContinueError = FALSE, ContinueSuccess = TRUE, ContinueProcessorReselected, ContinueNextProcessor }
enum | _ECHANNEL_STATE { ClientIdle, ClientSendWaitReply, ClientShutdown, ServerIdle, ServerReceiveMessage, ServerShutdown }
enum | _KBUGCHECK_BUFFER_DUMP_STATE { BufferEmpty, BufferInserted, BufferStarted, BufferFinished, BufferIncomplete }
enum | _FIRMWARE_REENTRY { HalHaltRoutine, HalPowerDownRoutine, HalRestartRoutine, HalRebootRoutine, HalInteractiveModeRoutine, HalMaximumRoutine }
enum | _MEMORY_CACHING_TYPE_ORIG { MmFrameBufferCached = 2 }
enum | _MEMORY_CACHING_TYPE { MmNonCached = FALSE, MmCached = TRUE, MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType }

## Functions

NTKERNELAPI VOID | KeInitializeApc (IN PRKAPC Apc, IN PRKTHREAD Thread, IN KAPC_ENVIRONMENT Environment, IN PKKERNEL_ROUTINE KernelRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL, IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL, IN KPROCESSOR_MODE ProcessorMode OPTIONAL, IN PVOID NormalContext OPTIONAL)
PLIST_ENTRY | KeFlushQueueApc (IN PKTHREAD Thread, IN KPROCESSOR_MODE ProcessorMode)
NTKERNELAPI BOOLEAN | KeInsertQueueApc (IN PRKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY Increment)
BOOLEAN | KeRemoveQueueApc (IN PKAPC Apc)
NTKERNELAPI VOID | KeInitializeDpc (IN PRKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
NTKERNELAPI BOOLEAN | KeInsertQueueDpc (IN PRKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
NTKERNELAPI BOOLEAN | KeRemoveQueueDpc (IN PRKDPC Dpc)
NTKERNELAPI VOID | KeSetImportanceDpc (IN PRKDPC Dpc, IN KDPC_IMPORTANCE Importance)
NTKERNELAPI VOID | KeSetTargetProcessorDpc (IN PRKDPC Dpc, IN CCHAR Number)
NTKERNELAPI VOID | KeInitializeDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue)
NTKERNELAPI BOOLEAN | KeInsertDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
NTKERNELAPI BOOLEAN | KeInsertByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey)
NTKERNELAPI PKDEVICE_QUEUE_ENTRY | KeRemoveDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue)
NTKERNELAPI PKDEVICE_QUEUE_ENTRY | KeRemoveByKeyDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey)
NTKERNELAPI BOOLEAN | KeRemoveEntryDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
NTKERNELAPI VOID | KeInitializeInterrupt (IN PKINTERRUPT Interrupt, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock OPTIONAL, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN CCHAR ProcessorNumber, IN BOOLEAN FloatingSave)
NTKERNELAPI BOOLEAN | KeConnectInterrupt (IN PKINTERRUPT Interrupt)
NTKERNELAPI BOOLEAN | KeDisconnectInterrupt (IN PKINTERRUPT Interrupt)
NTKERNELAPI BOOLEAN | KeSynchronizeExecution (IN PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext)
VOID | KeInitializeProfile (IN PKPROFILE Profile, IN PKPROCESS Process OPTIONAL, IN PVOID RangeBase, IN SIZE_T RangeSize, IN ULONG BucketSize, IN ULONG Segment, IN KPROFILE_SOURCE ProfileSource, IN KAFFINITY Affinity)
BOOLEAN | KeStartProfile (IN PKPROFILE Profile, IN PULONG Buffer)
BOOLEAN | KeStopProfile (IN PKPROFILE Profile)
VOID | KeSetIntervalProfile (IN ULONG Interval, IN KPROFILE_SOURCE Source)
ULONG | KeQueryIntervalProfile (IN KPROFILE_SOURCE Source)
NTKERNELAPI LONG | KePulseEvent (IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
NTKERNELAPI LONG | KeReadStateEvent (IN PRKEVENT Event)
NTKERNELAPI LONG | KeResetEvent (IN PRKEVENT Event)
NTKERNELAPI LONG | KeSetEvent (IN PRKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
VOID | KeSetEventBoostPriority (IN PRKEVENT Event, IN PRKTHREAD *Thread OPTIONAL)
VOID | KeInitializeEventPair (IN PKEVENT_PAIR EventPair)
NTKERNELAPI VOID | KeInitializeMutant (IN PRKMUTANT Mutant, IN BOOLEAN InitialOwner)
LONG | KeReadStateMutant (IN PRKMUTANT)
NTKERNELAPI LONG | KeReleaseMutant (IN PRKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandoned, IN BOOLEAN Wait)
NTKERNELAPI VOID | KeInitializeMutex (IN PRKMUTEX Mutex, IN ULONG Level)
NTKERNELAPI LONG | KeReleaseMutex (IN PRKMUTEX Mutex, IN BOOLEAN Wait)
NTKERNELAPI VOID | KeInitializeQueue (IN PRKQUEUE Queue, IN ULONG Count OPTIONAL)
NTKERNELAPI LONG | KeReadStateQueue (IN PRKQUEUE Queue)
NTKERNELAPI LONG | KeInsertQueue (IN PRKQUEUE Queue, IN PLIST_ENTRY Entry)
NTKERNELAPI LONG | KeInsertHeadQueue (IN PRKQUEUE Queue, IN PLIST_ENTRY Entry)
NTKERNELAPI PLIST_ENTRY | KeRemoveQueue (IN PRKQUEUE Queue, IN KPROCESSOR_MODE WaitMode, IN PLARGE_INTEGER Timeout OPTIONAL)
PLIST_ENTRY | KeRundownQueue (IN PRKQUEUE Queue)
NTKERNELAPI VOID | KeInitializeSemaphore (IN PRKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
NTKERNELAPI LONG | KeReadStateSemaphore (IN PRKSEMAPHORE Semaphore)
NTKERNELAPI LONG | KeReleaseSemaphore (IN PRKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
VOID | KeInitializeProcess (IN PRKPROCESS Process, IN KPRIORITY Priority, IN KAFFINITY Affinity, IN ULONG_PTR DirectoryTableBase[2], IN BOOLEAN Enable)
LOGICAL | KeForceAttachProcess (IN PKPROCESS Process)
NTKERNELAPI VOID | KeAttachProcess (IN PRKPROCESS Process)
NTKERNELAPI VOID | KeDetachProcess (VOID)
NTKERNELAPI VOID | KeStackAttachProcess (IN PRKPROCESS PROCESS, OUT PRKAPC_STATE ApcState)
NTKERNELAPI VOID | KeUnstackDetachProcess (IN PRKAPC_STATE ApcState)
LONG | KeReadStateProcess (IN PRKPROCESS Process)
BOOLEAN | KeSetAutoAlignmentProcess (IN PRKPROCESS Process, IN BOOLEAN Enable)
LONG | KeSetProcess (IN PRKPROCESS Process, IN KPRIORITY Increment, IN BOOLEAN Wait)
KPRIORITY | KeSetPriorityProcess (IN PKPROCESS Process, IN KPRIORITY BasePriority)
LOGICAL | KeSetDisableQuantumProcess (IN PKPROCESS Process, IN LOGICAL Disable)
VOID | KeInitializeThread (IN PKTHREAD Thread, IN PVOID KernelStack, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL, IN PCONTEXT ContextFrame OPTIONAL, IN PVOID Teb OPTIONAL, IN PKPROCESS Process)
BOOLEAN | KeAlertThread (IN PKTHREAD Thread, IN KPROCESSOR_MODE ProcessorMode)
ULONG | KeAlertResumeThread (IN PKTHREAD Thread)
NTKERNELAPI VOID | KeBoostCurrentThread (VOID)
VOID | KeBoostPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Increment)
KAFFINITY | KeConfineThread (VOID)
NTKERNELAPI NTSTATUS | KeDelayExecutionThread (IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval)
BOOLEAN | KeDisableApcQueuingThread (IN PKTHREAD Thread)
BOOLEAN | KeEnableApcQueuingThread (IN PKTHREAD)
LOGICAL | KeSetDisableBoostThread (IN PKTHREAD Thread, IN LOGICAL Disable)
ULONG | KeForceResumeThread (IN PKTHREAD Thread)
VOID | KeFreezeAllThreads (VOID)
BOOLEAN | KeQueryAutoAlignmentThread (IN PKTHREAD Thread)
LONG | KeQueryBasePriorityThread (IN PKTHREAD Thread)
NTKERNELAPI KPRIORITY | KeQueryPriorityThread (IN PKTHREAD Thread)
BOOLEAN | KeReadStateThread (IN PKTHREAD Thread)
VOID | KeReadyThread (IN PKTHREAD Thread)
ULONG | KeResumeThread (IN PKTHREAD Thread)
VOID | KeRevertToUserAffinityThread (VOID)
VOID | KeRundownThread (VOID)
KAFFINITY | KeSetAffinityThread (IN PKTHREAD Thread, IN KAFFINITY Affinity)
VOID | KeSetSystemAffinityThread (IN KAFFINITY Affinity)
BOOLEAN | KeSetAutoAlignmentThread (IN PKTHREAD Thread, IN BOOLEAN Enable)
NTKERNELAPI LONG | KeSetBasePriorityThread (IN PKTHREAD Thread, IN LONG Increment)
NTKERNELAPI CCHAR | KeSetIdealProcessorThread (IN PKTHREAD Thread, IN CCHAR Processor)
NTKERNELAPI BOOLEAN | KeSetKernelStackSwapEnable (IN BOOLEAN Enable)
NTKERNELAPI KPRIORITY | KeSetPriorityThread (IN PKTHREAD Thread, IN KPRIORITY Priority)
ULONG | KeSuspendThread (IN PKTHREAD)
NTKERNELAPI VOID | KeTerminateThread (IN KPRIORITY Increment)
BOOLEAN | KeTestAlertThread (IN KPROCESSOR_MODE)
VOID | KeThawAllThreads (VOID)
NTKERNELAPI VOID | KeInitializeTimer (IN PKTIMER Timer)
NTKERNELAPI VOID | KeInitializeTimerEx (IN PKTIMER Timer, IN TIMER_TYPE Type)
NTKERNELAPI BOOLEAN | KeCancelTimer (IN PKTIMER)
NTKERNELAPI BOOLEAN | KeReadStateTimer (PKTIMER Timer)
NTKERNELAPI BOOLEAN | KeSetTimer (IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
NTKERNELAPI BOOLEAN | KeSetTimerEx (IN PKTIMER Timer, IN LARGE_INTEGER DueTime, IN LONG Period OPTIONAL, IN PKDPC Dpc OPTIONAL)
PVOID | KeCheckForTimer (IN PVOID p, IN ULONG Size)
VOID | KeClearTimer (IN PKTIMER Timer)
ULONGLONG | KeQueryTimerDueTime (IN PKTIMER Timer)
NTSTATUS | KiSetServerWaitClientEvent (IN PKEVENT SeverEvent, IN PKEVENT ClientEvent, IN ULONG WaitMode)
NTKERNELAPI NTSTATUS | KeWaitForMultipleObjects (IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, IN PKWAIT_BLOCK WaitBlockArray OPTIONAL)
NTKERNELAPI NTSTATUS | KeWaitForSingleObject (IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
VOID FASTCALL | KiSetPriorityThread (IN PRKTHREAD Thread, IN KPRIORITY Priority)
NTKERNELAPI VOID NTAPI | KeInitializeSpinLock (IN PKSPIN_LOCK SpinLock)
NTKERNELAPI KIRQL FASTCALL | KeAcquireSpinLockRaiseToSynch (IN PKSPIN_LOCK SpinLock)
NTKERNELAPI VOID | KeAcquireSpinLockAtDpcLevel (IN PKSPIN_LOCK SpinLock)
NTKERNELAPI VOID | KeReleaseSpinLockFromDpcLevel (IN PKSPIN_LOCK SpinLock)
NTKERNELAPI KIRQL | KeAcquireSpinLockRaiseToDpc (IN PKSPIN_LOCK SpinLock)
NTKERNELAPI VOID | KeReleaseSpinLock (IN PKSPIN_LOCK SpinLock, IN KIRQL NewIrql)
BOOLEAN | KeTryToAcquireSpinLock (IN PKSPIN_LOCK SpinLock, OUT PKIRQL OldIrql)
BOOLEAN | KeInitSystem (VOID)
BOOLEAN | KeGetBugMessageText (IN ULONG MessageId, IN PANSI_STRING ReturnedString OPTIONAL)
NTKERNELAPI DECLSPEC_NORETURN VOID NTAPI | KeBugCheck (IN ULONG BugCheckCode)
NTKERNELAPI DECLSPEC_NORETURN VOID | KeBugCheckEx (IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
NTKERNELAPI BOOLEAN | KeDeregisterBugCheckCallback (IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
NTKERNELAPI BOOLEAN | KeRegisterBugCheckCallback (IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord, IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Buffer, IN ULONG Length, IN PUCHAR Component)
NTKERNELAPI VOID | KeEnterKernelDebugger (VOID)
VOID | KeDumpMachineState (IN PKPROCESSOR_STATE ProcessorState, IN PCHAR Buffer, IN PULONG_PTR BugCheckParameters, IN ULONG NumberOfParameters, IN PKE_BUGCHECK_UNICODE_TO_ANSI UnicodeToAnsiRoutine)
VOID | KeContextFromKframes (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT ContextFrame)
VOID | KeContextToKframes (IN OUT PKTRAP_FRAME TrapFrame, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN PCONTEXT ContextFrame, IN ULONG ContextFlags, IN KPROCESSOR_MODE PreviousMode)
VOID __cdecl | KeSaveStateForHibernate (IN PKPROCESSOR_STATE ProcessorState)
VOID | KeCopyTrapDispatcher (VOID)
BOOLEAN FASTCALL | KeInvalidAccessAllowed (IN PVOID TrapInformation OPTIONAL)
NTKERNELAPI VOID | KeFlushCurrentTb (VOID)
NTKERNELAPI VOID | KeFlushEntireTb (IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
VOID | KeFlushMultipleTb (IN ULONG Number, IN PVOID *Virtual, IN BOOLEAN Invalid, IN BOOLEAN AllProcesors, IN PHARDWARE_PTE *PtePointer OPTIONAL, IN HARDWARE_PTE PteValue)
HARDWARE_PTE | KeFlushSingleTb (IN PVOID Virtual, IN BOOLEAN Invalid, IN BOOLEAN AllProcesors, IN PHARDWARE_PTE PtePointer, IN HARDWARE_PTE PteValue)
BOOLEAN | KeFreezeExecution (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
KCONTINUE_STATUS | KeSwitchFrozenProcessor (IN ULONG ProcessorNumber)
VOID | KeGetNonVolatileContextPointers (IN PKNONVOLATILE_CONTEXT_POINTERS NonVolatileContext)
NTKERNELAPI VOID | KeSetDmaIoCoherency (IN ULONG Attributes)
VOID | KeSetSystemTime (IN PLARGE_INTEGER NewTime, OUT PLARGE_INTEGER OldTime, IN BOOLEAN AdjustInterruptTime, IN PLARGE_INTEGER HalTimeToSet OPTIONAL)
NTKERNELAPI BOOLEAN | KeAddSystemServiceTable (IN PULONG_PTR Base, IN PULONG Count OPTIONAL, IN ULONG Limit, IN PUCHAR Number, IN ULONG Index)
NTKERNELAPI ULONGLONG | KeQueryInterruptTime (VOID)
NTKERNELAPI VOID | KeQuerySystemTime (OUT PLARGE_INTEGER CurrentTime)
NTKERNELAPI ULONG | KeQueryTimeIncrement (VOID)
NTKERNELAPI KAFFINITY | KeQueryActiveProcessors (VOID)
NTKERNELAPI VOID | KeSetTimeIncrement (IN ULONG MaximumIncrement, IN ULONG MimimumIncrement)
VOID | KeThawExecution (IN BOOLEAN Enable)
VOID | KeReturnToFirmware (IN FIRMWARE_REENTRY Routine)
VOID | KeStartAllProcessors (VOID)
VOID | KeBalanceSetManager (IN PVOID Context)
VOID | KeSwapProcessOrStack (IN PVOID Context)
NTKERNELAPI NTSTATUS | KeUserModeCallback (IN ULONG ApiNumber, IN PVOID InputBuffer, IN ULONG InputLength, OUT PVOID *OutputBuffer, OUT PULONG OutputLength)
PVOID | KeSwitchKernelStack (IN PVOID StackBase, IN PVOID StackLimit)
NTSTATUS | KeRaiseUserException (IN NTSTATUS ExceptionCode)
NTKERNELAPI PCONFIGURATION_COMPONENT_DATA | KeFindConfigurationEntry (IN PCONFIGURATION_COMPONENT_DATA Child, IN CONFIGURATION_CLASS Class, IN CONFIGURATION_TYPE Type, IN PULONG Key OPTIONAL)
NTKERNELAPI PCONFIGURATION_COMPONENT_DATA | KeFindConfigurationNextEntry (IN PCONFIGURATION_COMPONENT_DATA Child, IN CONFIGURATION_CLASS Class, IN CONFIGURATION_TYPE Type, IN PULONG Key OPTIONAL, IN PCONFIGURATION_COMPONENT_DATA *Resume)
NTKERNELAPI VOID FASTCALL | KeSetSwapContextNotifyRoutine (IN PSWAP_CONTEXT_NOTIFY_ROUTINE NotifyRoutine)
NTKERNELAPI VOID FASTCALL | KeSetThreadSelectNotifyRoutine (IN PTHREAD_SELECT_NOTIFY_ROUTINE NotifyRoutine)
NTKERNELAPI VOID FASTCALL | KeSetTimeUpdateNotifyRoutine (IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine)

## Variables

KAFFINITY | KeActiveProcessors
LARGE_INTEGER | KeBootTime
ULONGLONG | KeBootTimeBias
ULONGLONG | KeInterruptTimeBias
LIST_ENTRY | KeBugCheckCallbackListHead
KSPIN_LOCK | KeBugCheckCallbackLock
PGDI_BATCHFLUSH_ROUTINE | KeGdiFlushUserBatch
PLOADER_PARAMETER_BLOCK | KeLoaderBlock
ULONG | KeMaximumIncrement
ULONG | KeMinimumIncrement
CCHAR | KeNumberProcessors
USHORT | KeProcessorArchitecture
USHORT | KeProcessorLevel
USHORT | KeProcessorRevision
ULONG | KeFeatureBits
CCHAR | KiFindFirstSetRight [256]
PKPRCB | KiProcessorBlock []
ULONG | KiStackProtectTime
KTHREAD_SWITCH_COUNTERS | KeThreadSwitchCounters
ULONG | KeRegisteredProcessors
ULONG | KeLicensedProcessors
PULONG | KeServiceCountTable
KSERVICE_TABLE_DESCRIPTOR | KeServiceDescriptorTable [NUMBER_SERVICE_TABLES]
KSERVICE_TABLE_DESCRIPTOR | KeServiceDescriptorTableShadow [NUMBER_SERVICE_TABLES]
volatile KSYSTEM_TIME | KeTickCount
PVOID | KeUserApcDispatcher
PVOID | KeUserCallbackDispatcher
PVOID | KeUserExceptionDispatcher
PVOID | KeRaiseUserExceptionDispatcher
ULONG | KeTimeAdjustment
ULONG | KeTimeIncrement
BOOLEAN | KeTimeSynchronization

## Define Documentation

#define _DECL_HAL_KE_IMPORT

| Definition at line 1793 of file ke.h.

#define BASE_PRIORITY_THRESHOLD NORMAL_BASE_PRIORITY

| Definition at line 76 of file ke.h. Referenced by main().

#define CLOCK_QUANTUM_DECREMENT 3

| Definition at line 28 of file ke.h. Referenced by KeUpdateRunTime(), KiDecrementQuantum(), and main().

#define DISPATCHER_OBJECT_TYPE_MASK 0x7

| Definition at line 120 of file ke.h.

#define DMA_READ_DCACHE_INVALIDATE 0x1

| Definition at line 2496 of file ke.h. Referenced by KeFlushIoBuffers(), and KiInitializeKernel().

#define DMA_READ_ICACHE_INVALIDATE 0x2

| Definition at line 2497 of file ke.h. Referenced by KeFlushIoBuffers().

#define DMA_WRITE_DCACHE_SNOOP 0x4

| Definition at line 2498 of file ke.h. Referenced by KeFlushIoBuffers(), and KiInitializeKernel().

#define EVENT_WAIT_BLOCK 2

| Definition at line 82 of file ke.h.

#define IIS_SERVICE_INDEX 2

| Definition at line 2547 of file ke.h.

#define KeAcquireSpinLock | ( | SpinLock,
|  | OldIrql |  | ) | *(OldIrql) = KeAcquireSpinLockRaiseToDpc(SpinLock)

| Definition at line 2007 of file ke.h. Referenced by ExFreePool(), ExLockPool(), ExNotifyCallback(), ExRegisterCallback(), ExUnregisterCallback(), KdDeregisterDebuggerDataBlock(), KdpTimeSlipWork(), KdRegisterDebuggerDataBlock(), KdUpdateTimeSlipEvent(), KeRestoreMtrr(), KeSetPhysicalCacheTypeRange(), KeSweepDcache(), KeSweepIcache(), KiAmdK6InitializeMTRR(), KiAmdK6MtrrSetMemoryType(), MemPrint(), MemPrintFlush(), MemPrintWriteCompleteApc(), MemPrintWriteThread(), PspDeleteVdmObjects(), RtlAcquireRemoveLockEx(), RtlReleaseRemoveLock(), UdfAddToWorkque(), UdfFspDispatch(), VdmpDelayIntApcRoutine(), VdmpDelayIntDpcRoutine(), VdmpDelayInterrupt(), and VerifierKeAcquireSpinLock().

#define KeClearEvent | ( | Event |  | ) | (Event)->Header.SignalState = 0

| Definition at line 1072 of file ke.h. Referenced by BuildQueryDirectoryIrp(), ClearQueueServerEvent(), ExUnregisterCallback(), IoCancelFileOpen(), IopCloseFile(), IopDeleteFile(), IopGetSetSecurityObject(), IopInvalidateVolumesForDevice(), IopLockDeviceRemovalRelations(), IopMountVolume(), IopProcessRelation(), IopQueryXxxInformation(), IopRequestDeviceAction(), IopSetEaOrQuotaInformationFile(), IopWaitForBootDevicesStarted(), IopXxxControlFile(), IoSetInformation(), IoShutdownSystem(), LfsFlushLfcb(), MiCheckForCrashDump(), MiCleanSection(), MiCreateImageFileMap(), MiDereferenceSegmentThread(), MiEmptyAllWorkingSets(), MiEnsureAvailablePageOrWait(), MiFlushSectionInternal(), MiGatherPagefilePages(), MiGetEventCounter(), MiGetInPageSupportBlock(), MiMakeOutswappedPageResident(), MiMappedPageWriter(), MiModifiedPageWriterWorker(), MmShutdownSystem(), NtClearEvent(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtNotifyChangeMultipleKeys(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetInformationFile(), NtSetInformationJobObject(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), NtWriteFileGather(), PsLockProcess(), UdfWaitSync(), VdmQueryDirectoryFile(), and xxxSleepTask().

#define KeEnterCriticalRegion | (

)

KeGetCurrentThread()->KernelApcDisable -= 1;

| Definition at line 1598 of file ke.h. Referenced by CmpLockRegistry(), CmpLockRegistryExclusive(), EnterCrit(), EnterMediaCrit(), EnterPowerCrit(), EnterSharedCrit(), ExChangeHandle(), ExCreateHandle(), ExDestroyHandle(), ExDupHandleTable(), ExEnumHandleTable(), ExpAllocateHandleTable(), ExRemoveHandleTable(), ExSnapShotHandleTables(), ExUuidCreate(), FsRecLoadFileSystem(), IoGetDeviceInterfaceAlias(), IoGetDeviceProperty(), IoOpenDeviceInterfaceRegistryKey(), IoOpenDeviceRegistryKey(), IopAllocateBootResources(), IopAllocateResources(), IopCreateMadeupNode(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDoDeferredSetInterfaceState(), IopDriverLoadingFailed(), IopGetDeviceInterfaces(), IopGetDriverDeviceList(), IopGetRootDevices(), IopGetSetSecurityObject(), IopInvalidateVolumesForDevice(), IopIsFirmwareDisabled(), IopLegacyResourceAllocation(), IopMakeGloballyUniqueId(), IopParseDevice(), IopPrepareDriverLoading(), IopProcessNewDeviceNode(), IopQueryConflictList(), IopReallocateResources(), IopRebalance(), IopRegisterDeviceInterface(), IopReleaseDeviceResources(), IopSetDeviceSecurityDescriptors(), IopStartAndEnumerateDevice(), IopUnlockDeviceRemovalRelations(), IopUnregisterDeviceInterface(), IopWriteAllocatedResourcesToRegistry(), IoReportDetectedDevice(), IoSetDeviceInterfaceState(), KeFreezeAllThreads(), LeaveMouseCrit(), LpcRequestPort(), MiCheckControlAreaStatus(), MiCheckPurgeAndUpMapCount(), MiCleanSection(), MiDereferenceSession(), MiDispatchFault(), MiEnablePagingTheExecutive(), MiFindInitializationCode(), MiFlushSectionInternal(), MiLoadSystemImage(), MiLookupDataTableEntry(), MiLookupPsLoadedModule(), MiMapImageHeaderInHyperSpace(), MiMapViewOfImageSection(), MiResolveTransitionFault(), MmAddVerifierThunks(), MmCleanProcessAddressSpace(), MmCopyToCachedPage(), MmExtendSection(), MmGetSectionRange(), MmGetSystemRoutineAddress(), MmGetVerifierInformation(), MmLockPagableDataSection(), MmLockPagableSectionByHandle(), MmPurgeSection(), MmSessionCreate(), MmSessionDelete(), MmSetVerifierInformation(), MmUnloadSystemImage(), NtAllocateUuids(), NtAssignProcessToJobObject(), NtClose(), NtDuplicateObject(), NtLoadKey2(), NtQueryInformationJobObject(), NtQuerySystemInformation(), NtReplaceKey(), NtRequestPort(), NtSetInformationJobObject(), NtSetInformationProcess(), NtTerminateJobObject(), NtUserUserHandleGrantAccess(), NtWaitForMultipleObjects(), ObFindHandleForObject(), ObInitProcess(), ObKillProcess(), ObpAcquireDescriptorCacheReadLock(), ObpAcquireDescriptorCacheWriteLock(), ObQueryObjectAuditingByHandle(), ObReferenceObjectByHandle(), PsChangeJobMemoryUsage(), PsLockProcess(), PspAddProcessToJob(), PspExitProcessFromJob(), PspExitThread(), PspJobClose(), PspJobDelete(), PspRemoveProcessFromJob(), PspSetQuotaLimits(), PsReportProcessMemoryLimitViolation(), and xxxUserProcessCallout().

#define KeFindFirstSetRightMember | ( | Set |  | ) |

Value:

    ((Set & 0xFF) ? KiFindFirstSetRight[Set & 0xFF] : \
        ((Set & 0xFF00) ? KiFindFirstSetRight[(Set >> 8) & 0xFF] + 8 : \
        ((Set & 0xFF0000) ? KiFindFirstSetRight[(Set >> 16) & 0xFF] + 16 : \
                               KiFindFirstSetRight[Set >> 24] + 24 )))

Definition at line 2293 of file ke.h.

Referenced by KeFreezeExecution(), KeI386SetGdtSelector(), KeThawExecution(), KiFlushForwardProgressTbBuffer(), and KiInvalidateForwardProgressTbBuffer().

#define KeGetCurrentApcEnvironment | (

)

KeGetCurrentThread()->ApcStateIndex

| Definition at line 100 of file ke.h. Referenced by IoInitializeIrp().

#define KeInitializeCallbackRecord | ( | CallbackRecord |  | ) | (CallbackRecord)->State = BufferEmpty

| Definition at line 2187 of file ke.h.

#define KeInitializeEvent | ( | _Event,
|  | _Type,
|  | _State |  | ) |

Value:

    (_Event)->Header.Type = (UCHAR)_Type;                   \
        (_Event)->Header.Size =  sizeof(KEVENT) / sizeof(LONG); \
        (_Event)->Header.SignalState = _State;                  \
        InitializeListHead(&(_Event)->Header.WaitListHead)

Definition at line 1066 of file ke.h.

Referenced by ArbInitializeArbiterInstance(), CcCanIWrite(), CcInitializeCacheMap(), CcSetValidData(), CcWaitForCurrentLazyWriterActivity(), CcWaitOnActiveCount(), CcZeroData(), CmpAllocatePostBlock(), CreateKernelEvent(), DriverEntry(), ExInitializeResource(), ExpAcquireResourceExclusiveLite(), ExpAllocateHandleTable(), ExpGetProcessInformation(), ExpInitializeCallbacks(), ExpWorkerInitialization(), ExReinitializeResourceLite(), FsRecGetDeviceSectors(), FsRecGetDeviceSectorSize(), FsRecReadBlock(), FsRtlBalanceReads(), FsRtlGetFileSize(), FsRtlSetFileSize(), FsRtlSyncVolumes(), FsRtlWaitOnIrp(), GetDeviceChangeInfo(), HalpEnableAutomaticDriveLetterAssignment(), HalpGetFullGeometry(), HalpIsOldStyleFloppy(), HalpNextMountLetter(), HalpQueryDriveLayout(), HalpQueryPartitionType(), HalpSetMountLetter(), IoCancelFileOpen(), IoCreateDevice(), IoCreateStreamFileObject(), IoCreateStreamFileObjectLite(), IoFreeDumpStack(), IoGetBootDiskInformation(), IoGetDmaAdapter(), IoInitializeRemoveLockEx(), IoInitSystem(), IopAllocateDeviceNode(), IopCloseFile(), IopCompleteUnloadOrDelete(), IopCreateArcNames(), IopDeleteFile(), IopFilterResourceRequirementsCall(), IopGetDumpStack(), IopGetFileName(), IopGetSetObjectId(), IopGetSetSecurityObject(), IopGetVolumeId(), IopInitializePlugPlayServices(), IopInvalidateVolumesForDevice(), IopLoadFileSystemDriver(), IopMountVolume(), IoPnPDeliverServicePowerNotification(), IopParseDevice(), IopQueryXxxInformation(), IopRequestHwProfileChangeNotification(), IopSetEaOrQuotaInformationFile(), IopSetRemoteLink(), IopSynchronousCall(), IoReportTargetDeviceChange(), IoSetInformation(), IoShutdownSystem(), IoSynchronousInvalidateDeviceRelations(), IoVerifyVolume(), IovpThrowBogusSynchronousIrp(), KeInitializeEventPair(), KeSetAutoAlignmentThread(), KiInitSystem(), LfsAllocateLfcb(), LfsInitializeLogFileService(), LpcpCreatePort(), LpcpInitializePortZone(), MemPrintInitialize(), MiAdjustWorkingSetManagerParameters(), MiChargeCommitment(), MiCheckForCrashDump(), MiCheckPageFilePath(), MiCleanSection(), MiCreateImageFileMap(), MiDereferenceSession(), MiFlushSectionInternal(), MiGetEventCounter(), MiGetInPageSupportBlock(), MiMakeOutswappedPageResident(), MiMappedPageWriter(), MiModifiedPageWriter(), MiSectionInitialization(), MmCleanProcessAddressSpace(), MmInitSystem(), MmShutdownSystem(), NtCreateChannel(), NtCreateEvent(), NtCreateJobObject(), NtCreatePagingFile(), NtFlushBuffersFile(), NtGetContextThread(), NtLoadDriver(), NtOpenChannel(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtSetContextThread(), NtSetEaFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnloadDriver(), NtUnlockFile(), ObInitSystem(), obtest(), PspCreateProcess(), QueuePowerRequest(), RtlAllocateRemoveLock(), RtlVolumeDeviceToDosName(), SmbTraceCompleteRdr(), SmbTraceCompleteSrv(), SmbTraceInitialize(), UdfCommonRead(), UdfPerformDevIoCtrl(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfReadSectors(), VdmQueryDirectoryFile(), xHalExamineMBR(), xHalGetPartialGeometry(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), and xHalIoWritePartitionTable().

#define KeIsAttachedProcess | (

)

(KeGetCurrentThread()->ApcStateIndex == AttachedApcEnvironment)

| Definition at line 1302 of file ke.h. Referenced by MiAccessCheck(), NtNotifyChangeMultipleKeys(), and PspExitThread().

#define KeLeaveCriticalRegion | (

)

KiLeaveCriticalRegion()

| Definition at line 1628 of file ke.h. Referenced by CmpUnlockRegistry(), ExChangeHandle(), ExCreateHandle(), ExDestroyHandle(), ExDupHandleTable(), ExEnumHandleTable(), ExpAllocateHandleTable(), ExRemoveHandleTable(), ExSnapShotHandleTables(), ExUuidCreate(), FsRecLoadFileSystem(), IoGetDeviceInterfaceAlias(), IoGetDeviceProperty(), IoOpenDeviceInterfaceRegistryKey(), IoOpenDeviceRegistryKey(), IopAllocateBootResources(), IopAllocateResources(), IopCreateMadeupNode(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDoDeferredSetInterfaceState(), IopDriverLoadingFailed(), IopGetDeviceInterfaces(), IopGetDriverDeviceList(), IopGetRootDevices(), IopGetSetSecurityObject(), IopInvalidateVolumesForDevice(), IopIsFirmwareDisabled(), IopLegacyResourceAllocation(), IopMakeGloballyUniqueId(), IopParseDevice(), IopPrepareDriverLoading(), IopProcessNewDeviceNode(), IopQueryConflictList(), IopReallocateResources(), IopRebalance(), IopRegisterDeviceInterface(), IopReleaseDeviceResources(), IopSetDeviceSecurityDescriptors(), IopStartAndEnumerateDevice(), IopUnlockDeviceRemovalRelations(), IopUnregisterDeviceInterface(), IopWriteAllocatedResourcesToRegistry(), IoReportDetectedDevice(), IoSetDeviceInterfaceState(), KeThawAllThreads(), LeaveCrit(), LeaveMediaCrit(), LeavePowerCrit(), LpcRequestPort(), MiCheckControlAreaStatus(), MiCheckPurgeAndUpMapCount(), MiCleanSection(), MiDereferenceSession(), MiDispatchFault(), MiEnablePagingTheExecutive(), MiFindInitializationCode(), MiFlushSectionInternal(), MiLoadSystemImage(), MiLookupDataTableEntry(), MiLookupPsLoadedModule(), MiMapImageHeaderInHyperSpace(), MiMapViewOfImageSection(), MiResolveTransitionFault(), MmAddVerifierThunks(), MmCleanProcessAddressSpace(), MmCopyToCachedPage(), MmExtendSection(), MmGetSectionRange(), MmGetSystemRoutineAddress(), MmGetVerifierInformation(), MmLockPagableDataSection(), MmLockPagableSectionByHandle(), MmPurgeSection(), MmSessionCreate(), MmSessionDelete(), MmSetVerifierInformation(), MmUnloadSystemImage(), NtAllocateUuids(), NtAssignProcessToJobObject(), NtClose(), NtDuplicateObject(), NtLoadKey2(), NtQueryInformationJobObject(), NtQuerySystemInformation(), NtReplaceKey(), NtRequestPort(), NtSetInformationJobObject(), NtSetInformationProcess(), NtSystemDebugControl(), NtTerminateJobObject(), NtUserUserHandleGrantAccess(), NtWaitForMultipleObjects(), ObFindHandleForObject(), ObInitProcess(), ObKillProcess(), ObpReleaseDescriptorCacheLock(), ObQueryObjectAuditingByHandle(), ObReferenceObjectByHandle(), PsChangeJobMemoryUsage(), PsLockProcess(), PspAddProcessToJob(), PspExitProcessFromJob(), PspExitThread(), PspJobClose(), PspJobDelete(), PspRemoveProcessFromJob(), PspSetQuotaLimits(), PsReportProcessMemoryLimitViolation(), PsUnlockProcess(), and xxxUserProcessCallout().

#define KeReadStateMutex | ( | Mutex |  | ) | KeReadStateMutant(Mutex)

| Definition at line 1171 of file ke.h.

#define KeSetHighEventPair | ( | EventPair,
|  | Increment,
|  | Wait |  | ) |

Value:

    KeSetEvent(&((EventPair)->EventHigh),              \
                   Increment,                              \
                   Wait)

Definition at line 1124 of file ke.h.

Referenced by NtSetHighEventPair().

#define KeSetHighWaitLowEventPair | ( | EventPair,
|  | WaitMode |  | ) |

Value:

    KiSetServerWaitClientEvent(&((EventPair)->EventHigh),               \
                                   &((EventPair)->EventLow),                \
                                   WaitMode)

Definition at line 1720 of file ke.h.

Referenced by NtSetHighWaitLowEventPair().

#define KeSetLowEventPair | ( | EventPair,
|  | Increment,
|  | Wait |  | ) |

Value:

    KeSetEvent(&((EventPair)->EventLow),               \
                   Increment,                              \
                   Wait)

Definition at line 1129 of file ke.h.

Referenced by NtSetLowEventPair().

#define KeSetLowWaitHighEventPair | ( | EventPair,
|  | WaitMode |  | ) |

Value:

    KiSetServerWaitClientEvent(&((EventPair)->EventLow),                \
                                   &((EventPair)->EventHigh),               \
                                   WaitMode)

Definition at line 1725 of file ke.h.

Referenced by NtSetLowWaitHighEventPair().

#define KeTerminateProcess | ( | Process |  | ) | (Process)->StackCount += 1;

| Definition at line 1335 of file ke.h. Referenced by PspProcessDelete().

#define KeWaitForHighEventPair | ( | EventPair,
|  | WaitMode,
|  | Alertable,
|  | TimeOut |  | ) |

Value:

    KeWaitForSingleObject(&((EventPair)->EventHigh),                    \
                              WrEventPair,                                  \
                              WaitMode,                                     \
                              Alertable,                                    \
                              TimeOut)

Definition at line 1730 of file ke.h.

Referenced by NtWaitHighEventPair().

#define KeWaitForLowEventPair | ( | EventPair,
|  | WaitMode,
|  | Alertable,
|  | TimeOut |  | ) |

Value:

    KeWaitForSingleObject(&((EventPair)->EventLow),                     \
                              WrEventPair,                                  \
                              WaitMode,                                     \
                              Alertable,                                    \
                              TimeOut)

Definition at line 1737 of file ke.h.

Referenced by NtWaitLowEventPair().

#define KeWaitForMutexObject KeWaitForSingleObject

| Definition at line 1746 of file ke.h.

#define KiLeaveCriticalRegion | (

)

Value:

    {                                       \
        PKTHREAD Thread;                                                    \
        Thread = KeGetCurrentThread();                                      \
        if (((*((volatile ULONG *)&Thread->KernelApcDisable) += 1) == 0) && \
            (((volatile LIST_ENTRY *)&Thread->ApcState.ApcListHead[KernelMode])->Flink != \
             &Thread->ApcState.ApcListHead[KernelMode])) {                  \
            Thread->ApcState.KernelApcPending = TRUE;                       \
            KiRequestSoftwareInterrupt(APC_LEVEL);                          \
        }                                                                   \
    }

Definition at line 1537 of file ke.h.

Referenced by KeLeaveCriticalRegion().

#define KiLockDispatcherDatabase | ( | OldIrql |  | ) | *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&KiDispatcherLock)

| Definition at line 1907 of file ke.h. Referenced by ExpCheckForWorker(), ExpFindCurrentThread(), ExpWaitForResource(), Ke386VdmClearApcObject(), Ke386VdmInsertQueueApc(), KeAlertResumeThread(), KeAlertThread(), KeAttachProcess(), KeAttachSessionSpace(), KeBalanceSetManager(), KeBoostCurrentThread(), KeBoostPriorityThread(), KeCancelTimer(), KeCheckForTimer(), KeConfineThread(), KeConnectInterrupt(), KeDelayExecutionThread(), KeDetachProcess(), KeDetachSessionSpace(), KeDisableApcQueuingThread(), KeDisableSessionSharing(), KeDisconnectInterrupt(), KeEnableApcQueuingThread(), KeEnableSessionSharing(), KeFlushQueueApc(), KeForceAttachProcess(), KeForceResumeThread(), KeFreezeAllThreads(), KeInitializeMutant(), KeInitializeThread(), KeInsertHeadQueue(), KeInsertQueue(), KeInsertQueueApc(), KePulseEvent(), KeQueryBasePriorityThread(), KeQueryTimerDueTime(), KeReadyThread(), KeReleaseMutant(), KeReleaseSemaphore(), KeRemoveQueue(), KeRemoveQueueApc(), KeResetEvent(), KeResumeThread(), KeRevertToUserAffinityThread(), KeRundownQueue(), KeRundownThread(), KeSetAffinityThread(), KeSetAutoAlignmentProcess(), KeSetAutoAlignmentThread(), KeSetBasePriorityThread(), KeSetDisableBoostThread(), KeSetEvent(), KeSetEventBoostPriority(), KeSetIdealProcessorThread(), KeSetPriorityProcess(), KeSetPriorityThread(), KeSetProcess(), KeSetSystemAffinityThread(), KeSetSystemTime(), KeSetTimerEx(), KeSetup80387OrEmulate(), KeStackAttachProcess(), KeSuspendThread(), KeSwapProcessOrStack(), KeTerminateThread(), KeTestAlertThread(), KeThawAllThreads(), KeUnstackDetachProcess(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), KiInSwapKernelStacks(), KiInSwapProcesses(), KiOutSwapKernelStacks(), KiOutSwapProcesses(), KiQuantumEnd(), KiScanReadyQueues(), KiTimerExpiration(), KiTimerListExpire(), NtReplyWaitSendChannel(), NtSendWaitReplyChannel(), NtYieldExecution(), and PspReaper().

#define LISTEN_CHANNEL 0x1

| Definition at line 802 of file ke.h. Referenced by NtCreateChannel().

#define MESSAGE_CHANNEL 0x2

| Definition at line 803 of file ke.h. Referenced by NtOpenChannel().

#define NUMBER_SERVICE_TABLES 4

| Definition at line 301 of file ke.h. Referenced by KeAddSystemServiceTable(), KiInitSystem(), and NtQuerySystemInformation().

#define READY_SKIP_QUANTUM 2

| Definition at line 35 of file ke.h. Referenced by KiFindReadyThread(), and main().

#define ROUND_TRIP_DECREMENT_COUNT 16

| Definition at line 42 of file ke.h. Referenced by ExpBoostOwnerThread(), KeBoostCurrentThread(), KiScanReadyQueues(), and main().

#define SEMAPHORE_WAIT_BLOCK 2

| Definition at line 83 of file ke.h.

#define SERVICE_NUMBER_MASK ((1 << 12) - 1)

| Definition at line 302 of file ke.h.

#define SERVICE_TABLE_MASK (((1 << 2) - 1) << 4)

| Definition at line 313 of file ke.h.

#define SERVICE_TABLE_SHIFT (12 - 4)

| Definition at line 312 of file ke.h.

#define SERVICE_TABLE_TEST (WIN32K_SERVICE_INDEX << 4)

| Definition at line 314 of file ke.h.

#define SYSTEM_SERVICE_INDEX 0

| Definition at line 2545 of file ke.h.

#define THREAD_QUANTUM (READY_SKIP_QUANTUM * CLOCK_QUANTUM_DECREMENT)

| Definition at line 36 of file ke.h. Referenced by KeInitializeProcess(), main(), PsChangeQuantumTable(), and PsSetProcessPriorityByClass().

#define THREAD_WAIT_OBJECTS 3

| Definition at line 79 of file ke.h. Referenced by KeInitializeThread(), KeWaitForMultipleObjects(), NtWaitForMultipleObjects(), and SmbTraceThreadEntry().

#define TIMER_TABLE_SIZE 128

| Definition at line 94 of file ke.h. Referenced by KeCheckForTimer(), KeSetSystemTime(), KiCalibrateTimeAdjustment(), KiChkTimerExpireSysDpc(), KiInitSystem(), and KiTimerExpiration().

#define TIMER_WAIT_BLOCK 3

| Definition at line 84 of file ke.h. Referenced by KeDelayExecutionThread(), KeInitializeThread(), KeWaitForMultipleObjects(), and KeWaitForSingleObject().

#define WAIT_QUANTUM_DECREMENT 1

| Definition at line 29 of file ke.h. Referenced by KiAdjustQuantumThread(), KiUnwaitThread(), and main().

#define WIN32K_SERVICE_INDEX 1

| Definition at line 2546 of file ke.h.

## Typedef Documentation

typedef struct _DISPATCHER_HEADER DISPATCHER_HEADER

typedef struct _ECHANNEL ECHANNEL

| Referenced by NtCreateChannel().

typedef enum _ECHANNEL_STATE ECHANNEL_STATE

typedef enum _FIRMWARE_REENTRY FIRMWARE_REENTRY

| Referenced by KeReturnToFirmware().

typedef enum _KAPC_ENVIRONMENT KAPC_ENVIRONMENT

| Referenced by KeInitializeApc().

typedef struct _KAPC_STATE KAPC_STATE

typedef enum _KBUGCHECK_BUFFER_DUMP_STATE KBUGCHECK_BUFFER_DUMP_STATE

typedef struct _KBUGCHECK_CALLBACK_RECORD KBUGCHECK_CALLBACK_RECORD

| Referenced by KiScanBugCheckCallbackList().

typedef struct _KDEVICE_QUEUE KDEVICE_QUEUE

| Referenced by KeInitializeDeviceQueue().

typedef struct _KDEVICE_QUEUE_ENTRY KDEVICE_QUEUE_ENTRY

| Referenced by KeInsertByKeyDeviceQueue().

typedef struct _KEVENT KEVENT

typedef struct _KEVENT_PAIR KEVENT_PAIR

| Referenced by KeInitializeEventPair().

typedef struct _KINTERRUPT KINTERRUPT

typedef enum _KINTERRUPT_MODE KINTERRUPT_MODE

typedef struct _KMUTANT KMUTANT

typedef struct _KMUTANT KMUTEX

typedef enum _KOBJECTS KOBJECTS

typedef ULONG KPAGE_FRAME

| Definition at line 272 of file ke.h.

typedef struct _KPROCESS KPROCESS

typedef enum _KPROCESS_STATE KPROCESS_STATE

typedef struct _KPROFILE KPROFILE

| Referenced by KiProcessProfileList().

typedef struct _KQUEUE KQUEUE

| Referenced by NtCreateIoCompletion().

typedef struct _KSEMAPHORE KSEMAPHORE

typedef struct _KSERVICE_TABLE_DESCRIPTOR KSERVICE_TABLE_DESCRIPTOR

typedef struct _KTHREAD KTHREAD

| Referenced by KeStartAllProcessors().

typedef enum _KTHREAD_STATE KTHREAD_STATE

typedef struct _KTHREAD_SWITCH_COUNTERS KTHREAD_SWITCH_COUNTERS

typedef struct _KTIMER KTIMER

| Referenced by RawInputThread().

typedef struct _KWAIT_BLOCK KWAIT_BLOCK

| Referenced by KeBalanceSetManager().

typedef enum _KWAIT_REASON KWAIT_REASON

| Referenced by KeWaitForMultipleObjects(), and KeWaitForSingleObject().

typedef enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE

| Referenced by MiSweepCacheMachineDependent().

typedef enum _MEMORY_CACHING_TYPE_ORIG MEMORY_CACHING_TYPE_ORIG

typedef struct _ECHANNEL * PECHANNEL

| Referenced by NtOpenChannel().

typedef enum _FIRMWARE_REENTRY * PFIRMWARE_REENTRY

typedef VOID(* PGDI_BATCHFLUSH_ROUTINE)(VOID)

| Definition at line 2275 of file ke.h. Referenced by PsEstablishWin32Callouts().

typedef struct _KAPC_STATE * PKAPC_STATE

| Referenced by KeRemoveQueueApc().

typedef struct _KBUGCHECK_CALLBACK_RECORD * PKBUGCHECK_CALLBACK_RECORD

| Referenced by KeDeregisterBugCheckCallback().

typedef VOID(* PKBUGCHECK_CALLBACK_ROUTINE)(IN PVOID Buffer, IN ULONG Length)

| Definition at line 2149 of file ke.h. Referenced by KeRegisterBugCheckCallback().

typedef BOOLEAN(* PKDEBUG_ROUTINE)(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance)

| Definition at line 336 of file ke.h.

typedef BOOLEAN(* PKDEBUG_SWITCH_ROUTINE)(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN BOOLEAN SecondChance)

| Definition at line 347 of file ke.h.

typedef struct _KDEVICE_QUEUE * PKDEVICE_QUEUE

| Referenced by KeInitializeDeviceQueue().

typedef struct _KDEVICE_QUEUE_ENTRY * PKDEVICE_QUEUE_ENTRY

| Referenced by KeInsertDeviceQueue().

typedef PCHAR(* PKE_BUGCHECK_UNICODE_TO_ANSI)(IN PUNICODE_STRING UnicodeString, OUT PCHAR AnsiBuffer, IN ULONG MaxAnsiLength)

| Definition at line 2216 of file ke.h. Referenced by KiDumpParameterImages().

typedef struct _KEVENT * PKEVENT

typedef struct _KEVENT_PAIR * PKEVENT_PAIR

| Referenced by KeInitializeEventPair().

typedef struct _KINTERRUPT* PKINTERRUPT

| Definition at line 477 of file ke.h. Referenced by KeInitializeInterrupt().

typedef struct _KMUTANT * PKMUTANT

typedef struct _KMUTANT * PKMUTEX

| Referenced by KeReleaseMutex().

typedef struct _KPROCESS * PKPROCESS

| Referenced by KeStartAllProcessors().

typedef struct _KPROFILE * PKPROFILE

| Referenced by KiProcessProfileList().

typedef struct _KQUEUE * PKQUEUE

| Referenced by KiUnwaitThread().

typedef struct _KSEMAPHORE * PKSEMAPHORE

typedef BOOLEAN(* PKSERVICE_ROUTINE)(IN struct _KINTERRUPT *Interrupt, IN PVOID ServiceContext)

| Definition at line 440 of file ke.h. Referenced by KeInitializeInterrupt().

typedef struct _KSERVICE_TABLE_DESCRIPTOR * PKSERVICE_TABLE_DESCRIPTOR

| Referenced by NtQuerySystemInformation().

typedef VOID(* PKSTART_ROUTINE)(IN PVOID StartContext)

| Definition at line 367 of file ke.h. Referenced by KiInitializeKernel(), PsCreateSystemThread(), PspCreateThread(), SmbTraceStart(), xxxInitInput(), and xxxInitTerminal().

typedef VOID(* PKSYSTEM_ROUTINE)(IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL)

| Definition at line 379 of file ke.h. Referenced by KiInitializeContextThread(), and KiInitializeKernel().

typedef struct _KTHREAD * PKTHREAD

| Referenced by KeStartAllProcessors().

typedef struct _KTHREAD_SWITCH_COUNTERS * PKTHREAD_SWITCH_COUNTERS

typedef struct _KTIMER * PKTIMER

| Referenced by KiChkTimerExpireSysDpc().

typedef struct _KWAIT_BLOCK * PKWAIT_BLOCK

typedef struct _ECHANNEL PRECHANNEL

typedef struct _KAPC_STATE PRKAPC_STATE

typedef struct _KDEVICE_QUEUE PRKDEVICE_QUEUE

typedef struct _KDEVICE_QUEUE_ENTRY PRKDEVICE_QUEUE_ENTRY

typedef struct _KEVENT PRKEVENT

| Referenced by KeInitializeEvent().

typedef struct _KEVENT_PAIR PRKEVENT_PAIR

typedef struct _KINTERRUPT * RESTRICTED_POINTER PRKINTERRUPT

| Definition at line 477 of file ke.h.

typedef struct _KMUTANT PRKMUTANT

typedef struct _KMUTANT PRKMUTEX

typedef struct _KPROCESS PRKPROCESS

typedef struct _KPROFILE PRKPROFILE

typedef struct _KQUEUE PRKQUEUE

typedef struct _KSEMAPHORE PRKSEMAPHORE

typedef struct _KTHREAD PRKTHREAD

typedef struct _KTIMER PRKTIMER

typedef struct _KWAIT_BLOCK PRKWAIT_BLOCK

typedef VOID(FASTCALL * PSWAP_CONTEXT_NOTIFY_ROUTINE)(IN HANDLE OldThreadId, IN HANDLE NewThreadId)

| Definition at line 2713 of file ke.h.

typedef LOGICAL(FASTCALL * PTHREAD_SELECT_NOTIFY_ROUTINE)(IN HANDLE ThreadId)

| Definition at line 2731 of file ke.h.

typedef VOID(FASTCALL * PTIME_UPDATE_NOTIFY_ROUTINE)(IN HANDLE ThreadId, IN KPROCESSOR_MODE Mode)

| Definition at line 2748 of file ke.h.

## Enumeration Type Documentation

enum _ECHANNEL_STATE

Enumeration values:

  ClientIdle |
  ClientSendWaitReply |
  ClientShutdown |
  ServerIdle |
  ServerReceiveMessage |
  ServerShutdown |

Definition at line 805 of file ke.h.

    00805                              {
    00806     ClientIdle,
    00807     ClientSendWaitReply,
    00808     ClientShutdown,
    00809     ServerIdle,
    00810     ServerReceiveMessage,
    00811     ServerShutdown
    00812 } ECHANNEL_STATE;

enum _FIRMWARE_REENTRY

Enumeration values:

  HalHaltRoutine |
  HalPowerDownRoutine |
  HalRestartRoutine |
  HalRebootRoutine |
  HalInteractiveModeRoutine |
  HalMaximumRoutine |

Definition at line 2611 of file ke.h.

    02611                                {
    02612     HalHaltRoutine,
    02613     HalPowerDownRoutine,
    02614     HalRestartRoutine,
    02615     HalRebootRoutine,
    02616     HalInteractiveModeRoutine,
    02617     HalMaximumRoutine
    02618 } FIRMWARE_REENTRY, *PFIRMWARE_REENTRY;

enum _KAPC_ENVIRONMENT

Enumeration values:

  OriginalApcEnvironment |
  AttachedApcEnvironment |
  CurrentApcEnvironment |

Definition at line 153 of file ke.h.

    00153                                {
    00154     OriginalApcEnvironment,
    00155     AttachedApcEnvironment,
    00156     CurrentApcEnvironment
    00157     } KAPC_ENVIRONMENT;

enum _KBUGCHECK_BUFFER_DUMP_STATE

Enumeration values:

  BufferEmpty |
  BufferInserted |
  BufferStarted |
  BufferFinished |
  BufferIncomplete |

Definition at line 2139 of file ke.h.

    02139                                           {
    02140     BufferEmpty,
    02141     BufferInserted,
    02142     BufferStarted,
    02143     BufferFinished,
    02144     BufferIncomplete
    02145 } KBUGCHECK_BUFFER_DUMP_STATE;

enum _KINTERRUPT_MODE

Enumeration values:

  LevelSensitive |
  Latched |

Definition at line 165 of file ke.h.

    00165                               {
    00166     LevelSensitive,
    00167     Latched
    00168     } KINTERRUPT_MODE;

enum _KOBJECTS

Enumeration values:

  EventNotificationObject |
  EventSynchronizationObject |
  MutantObject |
  ProcessObject |
  QueueObject |
  SemaphoreObject |
  ThreadObject |
  Spare1Object |
  TimerNotificationObject |
  TimerSynchronizationObject |
  Spare2Object |
  Spare3Object |
  Spare4Object |
  Spare5Object |
  Spare6Object |
  Spare7Object |
  Spare8Object |
  Spare9Object |
  ApcObject |
  DpcObject |
  DeviceQueueObject |
  EventPairObject |
  InterruptObject |
  ProfileObject |

Definition at line 122 of file ke.h.

    00122                        {
    00123     EventNotificationObject = 0,
    00124     EventSynchronizationObject = 1,
    00125     MutantObject = 2,
    00126     ProcessObject = 3,
    00127     QueueObject = 4,
    00128     SemaphoreObject = 5,
    00129     ThreadObject = 6,
    00130     Spare1Object = 7,
    00131     TimerNotificationObject = 8,
    00132     TimerSynchronizationObject = 9,
    00133     Spare2Object = 10,
    00134     Spare3Object = 11,
    00135     Spare4Object = 12,
    00136     Spare5Object = 13,
    00137     Spare6Object = 14,
    00138     Spare7Object = 15,
    00139     Spare8Object = 16,
    00140     Spare9Object = 17,
    00141     ApcObject,
    00142     DpcObject,
    00143     DeviceQueueObject,
    00144     EventPairObject,
    00145     InterruptObject,
    00146     ProfileObject
    00147     } KOBJECTS;

enum _KPROCESS_STATE

Enumeration values:

  ProcessInMemory |
  ProcessOutOfMemory |
  ProcessInTransition |
  ProcessInSwap |
  ProcessOutSwap |

Definition at line 176 of file ke.h.

    00176                              {
    00177     ProcessInMemory,
    00178     ProcessOutOfMemory,
    00179     ProcessInTransition,
    00180     ProcessInSwap,
    00181     ProcessOutSwap
    00182     } KPROCESS_STATE;

enum _KTHREAD_STATE

Enumeration values:

  Initialized |
  Ready |
  Running |
  Standby |
  Terminated |
  Waiting |
  Transition |

Definition at line 188 of file ke.h.

    00188                             {
    00189     Initialized,
    00190     Ready,
    00191     Running,
    00192     Standby,
    00193     Terminated,
    00194     Waiting,
    00195     Transition
    00196     } KTHREAD_STATE;

enum _KWAIT_REASON

Enumeration values:

  Executive |
  FreePage |
  PageIn |
  PoolAllocation |
  DelayExecution |
  Suspended |
  UserRequest |
  WrExecutive |
  WrFreePage |
  WrPageIn |
  WrPoolAllocation |
  WrDelayExecution |
  WrSuspended |
  WrUserRequest |
  WrEventPair |
  WrQueue |
  WrLpcReceive |
  WrLpcReply |
  WrVirtualMemory |
  WrPageOut |
  WrRendezvous |
  Spare2 |
  Spare3 |
  Spare4 |
  Spare5 |
  Spare6 |
  WrKernel |
  MaximumWaitReason |

Definition at line 203 of file ke.h.

    00203                            {
    00204     Executive,
    00205     FreePage,
    00206     PageIn,
    00207     PoolAllocation,
    00208     DelayExecution,
    00209     Suspended,
    00210     UserRequest,
    00211     WrExecutive,
    00212     WrFreePage,
    00213     WrPageIn,
    00214     WrPoolAllocation,
    00215     WrDelayExecution,
    00216     WrSuspended,
    00217     WrUserRequest,
    00218     WrEventPair,
    00219     WrQueue,
    00220     WrLpcReceive,
    00221     WrLpcReply,
    00222     WrVirtualMemory,
    00223     WrPageOut,
    00224     WrRendezvous,
    00225     Spare2,
    00226     Spare3,
    00227     Spare4,
    00228     Spare5,
    00229     Spare6,
    00230     WrKernel,
    00231     MaximumWaitReason
    00232     } KWAIT_REASON;

enum _MEMORY_CACHING_TYPE

Enumeration values:

  MmNonCached |
  MmCached |
  MmWriteCombined |
  MmHardwareCoherentCached |
  MmNonCachedUnordered |
  MmUSWCCached |
  MmMaximumCacheType |

Definition at line 2824 of file ke.h.

    02824                                   {
    02825     MmNonCached = FALSE,
    02826     MmCached = TRUE,
    02827     MmWriteCombined = MmFrameBufferCached,
    02828     MmHardwareCoherentCached,
    02829     MmNonCachedUnordered,       // IA64
    02830     MmUSWCCached,
    02831     MmMaximumCacheType
    02832 } MEMORY_CACHING_TYPE;

enum _MEMORY_CACHING_TYPE_ORIG

Enumeration values:

  MmFrameBufferCached |

Definition at line 2820 of file ke.h.

    02820                                        {
    02821     MmFrameBufferCached = 2
    02822 } MEMORY_CACHING_TYPE_ORIG;

enum KCONTINUE_STATUS

Enumeration values:

  ContinueError |
  ContinueSuccess |
  ContinueProcessorReselected |
  ContinueNextProcessor |

Definition at line 353 of file ke.h.

Referenced by KdpReportExceptionStateChange(), KdpReportLoadSymbolsStateChange(), KdpSendWaitContinue(), and KiFreezeTargetExecution().

    00353              {
    00354     ContinueError = FALSE,
    00355     ContinueSuccess = TRUE,
    00356     ContinueProcessorReselected,
    00357     ContinueNextProcessor
    00358 } KCONTINUE_STATUS;

## Function Documentation

NTKERNELAPI VOID KeAcquireSpinLockAtDpcLevel | ( | IN PKSPIN_LOCK | SpinLock | ) |

NTKERNELAPI KIRQL KeAcquireSpinLockRaiseToDpc | ( | IN PKSPIN_LOCK | SpinLock | ) |

NTKERNELAPI KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch | ( | IN PKSPIN_LOCK | SpinLock | ) |

NTKERNELAPI BOOLEAN KeAddSystemServiceTable | ( | IN PULONG_PTR | Base,
|  | IN PULONG Count | OPTIONAL,
|  | IN ULONG | Limit,
|  | IN PUCHAR | Number,
|  | IN ULONG | Index
| ) |

Definition at line 815 of file ke/miscc.c.

References _KSERVICE_TABLE_DESCRIPTOR::Base, _KSERVICE_TABLE_DESCRIPTOR::Count, Count, FALSE, Index, KeServiceDescriptorTable, KeServiceDescriptorTableShadow, _KSERVICE_TABLE_DESCRIPTOR::Limit, NULL, _KSERVICE_TABLE_DESCRIPTOR::Number, NUMBER_SERVICE_TABLES, PAGED_CODE, and TRUE.

    00825                    :
    00826
    00827     This function allows the caller to add a system service table
    00828     to the system
    00829
    00830 Arguments:
    00831
    00832     Base - Supplies the address of the system service table dispatch
    00833         table.
    00834
    00835     Count - Supplies an optional pointer to a table of per system service
    00836         counters.
    00837
    00838     Limit - Supplies the limit of the service table. Services greater
    00839         than or equal to this limit will fail.
    00840
    00841     Arguments - Supplies the address of the argument count table.
    00842
    00843     Index - Supplies index of the service table.
    00844
    00845 Return Value:
    00846
    00847     TRUE - The operation was successful.
    00848
    00849     FALSE - the operation failed. A service table is already bound to
    00850         the specified location, or the specified index is larger than
    00851         the maximum allowed index.
    00852
    00853 --*/
    00854
    00855 {
    00856
    00857     PAGED_CODE();
    00858
    00859     //
    00860     // If a system service table is already defined for the specified
    00861     // index, then return FALSE. Otherwise, establish the new system
    00862     // service table.
    00863     //
    00864
    00865     if ((Index > NUMBER_SERVICE_TABLES - 1) ||
    00866         (KeServiceDescriptorTable[Index].Base != NULL) ||
    00867         (KeServiceDescriptorTableShadow[Index].Base != NULL)) {
    00868         return FALSE;
    00869
    00870     } else {
    00871
    00872         //
    00873         // If the service table index is equal to the Win32 table, then
    00874         // only update the shadow system service table. Otherwise, both
    00875         // the shadow and static system service tables are updated.
    00876         //
    00877
    00878         KeServiceDescriptorTableShadow[Index].Base = Base;
    00879         KeServiceDescriptorTableShadow[Index].Count = Count;
    00880         KeServiceDescriptorTableShadow[Index].Limit = Limit;
    00881 #if defined(_IA64_)
    00882
    00883             //
    00884             // The global pointer associated with the table base is
    00885             // placed just before the service table.
    00886             //
    00887
    00888             KeServiceDescriptorTableShadow[Index].TableBaseGpOffset =
    00889                 (LONG)(*(Base-1) - (ULONG_PTR)Base);
    00890 #endif
    00891         KeServiceDescriptorTableShadow[Index].Number = Number;
    00892         if (Index != 1) {
    00893             KeServiceDescriptorTable[Index].Base = Base;
    00894             KeServiceDescriptorTable[Index].Count = Count;
    00895             KeServiceDescriptorTable[Index].Limit = Limit;
    00896 #if defined(_IA64_)
    00897             KeServiceDescriptorTable[Index].TableBaseGpOffset =
    00898                 (LONG)(*(Base-1) - (ULONG_PTR)Base);
    00899 #endif
    00900             KeServiceDescriptorTable[Index].Number = Number;
    00901         }
    00902
    00903         return TRUE;
    00904     }
    00905 }

ULONG KeAlertResumeThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 365 of file thredobj.c.

References ALERT_INCREMENT, ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KernelMode, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiUnwaitThread(), KiWaitTest(), RESUME_INCREMENT, TRUE, and Waiting.

Referenced by NtAlertResumeThread().

    00371                    :
    00372
    00373     This function attempts to alert a thread in kernel mode and cause its
    00374     execution to be continued if it is currently in an alertable Wait state.
    00375     In addition, a resume operation is performed on the specified thread.
    00376
    00377 Arguments:
    00378
    00379     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00380
    00381 Return Value:
    00382
    00383     The previous suspend count.
    00384
    00385 --*/
    00386
    00387 {
    00388
    00389     ULONG OldCount;
    00390     KIRQL OldIrql;
    00391
    00392     ASSERT_THREAD(Thread);
    00393     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00394
    00395     //
    00396     // Raise IRQL to dispatcher level, lock dispatcher database, and lock
    00397     // APC queue.
    00398     //
    00399
    00400     KiLockDispatcherDatabase(&OldIrql);
    00401     KiAcquireSpinLock(&Thread->ApcQueueLock);
    00402
    00403     //
    00404     // If the kernel mode alerted state is FALSE, then attempt to alert
    00405     // the thread for kernel mode.
    00406     //
    00407
    00408     if (Thread->Alerted[KernelMode] == FALSE) {
    00409
    00410         //
    00411         // If the thread is currently in a Wait state and the Wait is alertable,
    00412         // then the thread is unwaited with a status of "alerted". Else set the
    00413         // kernel mode alerted variable.
    00414         //
    00415
    00416         if ((Thread->State == Waiting) && (Thread->Alertable == TRUE)) {
    00417             KiUnwaitThread(Thread, STATUS_ALERTED, ALERT_INCREMENT);
    00418
    00419         } else {
    00420             Thread->Alerted[KernelMode] = TRUE;
    00421         }
    00422     }
    00423
    00424     //
    00425     // Capture the current suspend count.
    00426     //
    00427
    00428     OldCount = Thread->SuspendCount;
    00429
    00430     //
    00431     // If the thread is currently suspended, then decrement its suspend count.
    00432     //
    00433
    00434     if (OldCount != 0) {
    00435         Thread->SuspendCount -= 1;
    00436
    00437         //
    00438         // If the resultant suspend count is zero and the freeze count is
    00439         // zero, then resume the thread by releasing its suspend semaphore.
    00440         //
    00441
    00442         if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) {
    00443             Thread->SuspendSemaphore.Header.SignalState += 1;
    00444             KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT);
    00445         }
    00446     }
    00447
    00448     //
    00449     // Unlock APC queue, unlock dispatcher database, lower IRQL to its
    00450     // previous value, and return the previous suspend count.
    00451     //
    00452
    00453     KiReleaseSpinLock(&Thread->ApcQueueLock);
    00454     KiUnlockDispatcherDatabase(OldIrql);
    00455     return OldCount;
    00456 }

BOOLEAN KeAlertThread | ( | IN PKTHREAD | Thread,
|  | IN KPROCESSOR_MODE | ProcessorMode
| ) |

Definition at line 281 of file thredobj.c.

References ALERT_INCREMENT, ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiUnwaitThread(), TRUE, and Waiting.

Referenced by NtAlertThread().

    00288                    :
    00289
    00290     This function attempts to alert a thread and cause its execution to
    00291     be continued if it is currently in an alertable Wait state. Otherwise
    00292     it just sets the alerted variable for the specified processor mode.
    00293
    00294 Arguments:
    00295
    00296     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00297
    00298     AlertMode - Supplies the processor mode for which the thread is
    00299         to be alerted.
    00300
    00301 Return Value:
    00302
    00303     The previous state of the alerted variable for the specified processor
    00304     mode.
    00305
    00306 --*/
    00307
    00308 {
    00309
    00310     BOOLEAN Alerted;
    00311     KIRQL OldIrql;
    00312
    00313     ASSERT_THREAD(Thread);
    00314     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00315
    00316     //
    00317     // Raise IRQL to dispatcher level, lock dispatcher database, and lock
    00318     // APC queue.
    00319     //
    00320
    00321     KiLockDispatcherDatabase(&OldIrql);
    00322     KiAcquireSpinLock(&Thread->ApcQueueLock);
    00323
    00324     //
    00325     // Capture the current state of the alerted variable for the specified
    00326     // processor mode.
    00327     //
    00328
    00329     Alerted = Thread->Alerted[AlertMode];
    00330
    00331     //
    00332     // If the alerted state for the specified processor mode is Not-Alerted,
    00333     // then attempt to alert the thread.
    00334     //
    00335
    00336     if (Alerted == FALSE) {
    00337
    00338         //
    00339         // If the thread is currently in a Wait state, the Wait is alertable,
    00340         // and the specified processor mode is less than or equal to the Wait
    00341         // mode, then the thread is unwaited with a status of "alerted".
    00342         //
    00343
    00344         if ((Thread->State == Waiting) && (Thread->Alertable == TRUE) &&
    00345             (AlertMode <= Thread->WaitMode)) {
    00346             KiUnwaitThread(Thread, STATUS_ALERTED, ALERT_INCREMENT);
    00347
    00348         } else {
    00349             Thread->Alerted[AlertMode] = TRUE;
    00350         }
    00351     }
    00352
    00353     //
    00354     // Unlock APC queue, unlock dispatcher database, lower IRQL to its
    00355     // previous value, and return the previous alerted state for the
    00356     // specified mode.
    00357     //
    00358
    00359     KiReleaseSpinLock(&Thread->ApcQueueLock);
    00360     KiUnlockDispatcherDatabase(OldIrql);
    00361     return Alerted;
    00362 }

NTKERNELAPI VOID KeAttachProcess | ( | IN PRKPROCESS | Process | ) |

Definition at line 166 of file procobj.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, FALSE, KeBugCheckEx(), KeGetCurrentThread, KiAttachProcess(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), _KAPC_STATE::Process, and _KTHREAD::SavedApcState.

Referenced by _GetComboBoxInfo(), _GetListBoxInfo(), CheckWHFBits(), MiCloneProcessAddressSpace(), MiDoMappedCopy(), MiDoPoolCopy(), MiEmptyAllWorkingSetsWorker(), MiGetWorkingSetInfo(), MiLoadImageSection(), MiLoadSystemImage(), MmAssignProcessToJob(), MmCreatePeb(), MmCreateTeb(), MmDeleteTeb(), MmFlushVirtualMemory(), MmInitializeProcessAddressSpace(), MmMapViewOfSection(), MmProbeAndLockProcessPages(), MmSetBankedSection(), MmSetMemoryPriorityProcess(), MmUnmapViewOfSection(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtDuplicateObject(), NtFlushInstructionCache(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtLockVirtualMemory(), NtProtectVirtualMemory(), NtQueryVirtualMemory(), NtSetInformationJobObject(), NtSetInformationProcess(), NtUnlockVirtualMemory(), PsAssignImpersonationToken(), PspAddProcessToJob(), PspCreateProcess(), PspSetQuotaLimits(), SepRmCallLsa(), SetProcessFlags(), SmbTraceCompleteRdr(), SmbTraceDisconnect(), SmbTraceStop(), xxxCheckImeShowStatus(), xxxCreateDisconnectDesktop(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxImmActivateAndUnloadThreadsLayout(), xxxMinMaximize(), xxxNotifyImeShowStatus(), xxxSendMessageToUI(), and zzzSetWindowsHookEx().

    00172                    :
    00173
    00174     This function attaches a thread to a target process' address space
    00175     if, and only if, there is not already a process attached.
    00176
    00177 Arguments:
    00178
    00179     Process - Supplies a pointer to a dispatcher object of type process.
    00180
    00181 Return Value:
    00182
    00183     None.
    00184
    00185 --*/
    00186
    00187 {
    00188
    00189     KIRQL OldIrql;
    00190     PRKTHREAD Thread;
    00191
    00192     ASSERT_PROCESS(Process);
    00193     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00194
    00195     //
    00196     // Raise IRQL to dispatcher level and lock dispatcher database.
    00197     //
    00198
    00199     Thread = KeGetCurrentThread();
    00200     KiLockDispatcherDatabase(&OldIrql);
    00201
    00202     //
    00203     // If the target process is the current process, then return immediately.
    00204     // Otherwise, check whether there is a process address space attached or
    00205     // the thread is executing a DPC. If either condition is true, then call
    00206     // bug check. Otherwise, attach the target process.
    00207     //
    00208
    00209     if (Thread->ApcState.Process == Process) {
    00210         KiUnlockDispatcherDatabase(OldIrql);
    00211
    00212     } else if ((Thread->ApcStateIndex != 0) ||
    00213                (KeIsExecutingDpc() != FALSE)) {
    00214         KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
    00215                      (ULONG_PTR)Process,
    00216                      (ULONG_PTR)Thread->ApcState.Process,
    00217                      (ULONG)Thread->ApcStateIndex,
    00218                      (ULONG)KeIsExecutingDpc());
    00219
    00220     } else {
    00221         KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
    00222     }
    00223
    00224     return;
    00225 }

VOID KeBalanceSetManager | ( | IN PVOID | Context | ) |

Definition at line 142 of file balmgr.c.

References ExAdjustLookasideDepth(), EXECUTION_TIME_LIMITS_PERIOD, Executive, FALSE, KeGetCurrentThread, KeInitializeTimer(), KernelMode, KeSetEvent(), KeSetPriorityThread(), KeSetTimer(), KeWaitForMultipleObjects(), KiLockDispatcherDatabase, KiScanReadyQueues(), KiStackOutSwapRequest, KiStackProtectTime, KiSwapEvent, KiUnlockDispatcherDatabase(), KWAIT_BLOCK, MaximumObject, MmQuerySystemSize(), MmSmallSystem, MmWorkingSetManager(), MmWorkingSetManagerEvent, NTSTATUS(), NULL, PERIODIC_INTERVAL, PsEnforceExecutionTimeLimits(), SMALL_SYSTEM_STACK_PROTECT_TIME, STACK_PROTECT_TIME, STACK_SCAN_PERIOD, Status, TimerExpiration, TRUE, and WorkingSetManagerEvent.

Referenced by MmInitSystem().

    00148                    :
    00149
    00150     This function is the startup code for the balance set manager. The
    00151     balance set manager thread is created during system initialization
    00152     and begins execution in this function.
    00153
    00154 Arguments:
    00155
    00156     Context - Supplies a pointer to an arbitrary data structure (NULL).
    00157
    00158 Return Value:
    00159
    00160     None.
    00161
    00162 --*/
    00163
    00164 {
    00165
    00166     LARGE_INTEGER DueTime;
    00167     KTIMER PeriodTimer;
    00168     KIRQL OldIrql;
    00169     ULONG StackScanPeriod;
    00170     ULONG ExecutionTimeLimitPeriod;
    00171     NTSTATUS Status;
    00172     KWAIT_BLOCK WaitBlockArray[MaximumObject];
    00173     PVOID WaitObjects[MaximumObject];
    00174
    00175     //
    00176     // Raise the thread priority to the lowest realtime level.
    00177     //
    00178
    00179     KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);
    00180
    00181     //
    00182     // Initialize the periodic timer, set it to expire one period from
    00183     // now, and set the stack scan period.
    00184     //
    00185
    00186     KeInitializeTimer(&PeriodTimer);
    00187     DueTime.QuadPart = - PERIODIC_INTERVAL;
    00188     KeSetTimer(&PeriodTimer, DueTime, NULL);
    00189     StackScanPeriod = STACK_SCAN_PERIOD;
    00190     ExecutionTimeLimitPeriod = EXECUTION_TIME_LIMITS_PERIOD;
    00191     //
    00192     // Compute the stack protect time based on the system size.
    00193     //
    00194
    00195     if (MmQuerySystemSize() == MmSmallSystem) {
    00196         KiStackProtectTime = SMALL_SYSTEM_STACK_PROTECT_TIME;
    00197
    00198     } else {
    00199         KiStackProtectTime = STACK_PROTECT_TIME;
    00200     }
    00201
    00202     //
    00203     // Initialize the wait objects array.
    00204     //
    00205
    00206     WaitObjects[TimerExpiration] = (PVOID)&PeriodTimer;
    00207     WaitObjects[WorkingSetManagerEvent] = (PVOID)&MmWorkingSetManagerEvent;
    00208
    00209     //
    00210     // Loop forever processing balance set manager events.
    00211     //
    00212
    00213     do {
    00214
    00215         //
    00216         // Wait for a memory management memory low event, a swap event,
    00217         // or the expiration of the period timout rate that the balance
    00218         // set manager runs at.
    00219         //
    00220
    00221         Status = KeWaitForMultipleObjects(MaximumObject,
    00222                                           &WaitObjects[0],
    00223                                           WaitAny,
    00224                                           Executive,
    00225                                           KernelMode,
    00226                                           FALSE,
    00227                                           NULL,
    00228                                           &WaitBlockArray[0]);
    00229
    00230         //
    00231         // Switch on the wait status.
    00232         //
    00233
    00234         switch (Status) {
    00235
    00236             //
    00237             // Periodic timer expiration.
    00238             //
    00239
    00240         case TimerExpiration:
    00241
    00242             //
    00243             // Attempt to initiate outswaping of kernel stacks.
    00244             //
    00245
    00246             StackScanPeriod -= 1;
    00247             if (StackScanPeriod == 0) {
    00248                 StackScanPeriod = STACK_SCAN_PERIOD;
    00249                 KiLockDispatcherDatabase(&OldIrql);
    00250                 if (KiStackOutSwapRequest == FALSE) {
    00251                     KiStackOutSwapRequest = TRUE;
    00252                     KiUnlockDispatcherDatabase(OldIrql);
    00253                     KeSetEvent(&KiSwapEvent, 0, FALSE);
    00254
    00255                 } else {
    00256                     KiUnlockDispatcherDatabase(OldIrql);
    00257                 }
    00258             }
    00259
    00260             //
    00261             // Adjust the depth of lookaside lists.
    00262             //
    00263
    00264             ExAdjustLookasideDepth();
    00265
    00266             //
    00267             // Scan ready queues and boost thread priorities as appropriate.
    00268             //
    00269
    00270             KiScanReadyQueues();
    00271
    00272             //
    00273             // Execute the virtual memory working set manager.
    00274             //
    00275
    00276             MmWorkingSetManager();
    00277
    00278             //
    00279             // Enforce execution time limits
    00280             //
    00281
    00282             ExecutionTimeLimitPeriod -= 1;
    00283             if (ExecutionTimeLimitPeriod == 0) {
    00284                 ExecutionTimeLimitPeriod = EXECUTION_TIME_LIMITS_PERIOD;
    00285                 PsEnforceExecutionTimeLimits();
    00286                 }
    00287
    00288             //
    00289             // Set the timer to expire at the next periodic interval.
    00290             //
    00291
    00292             KeSetTimer(&PeriodTimer, DueTime, NULL);
    00293             break;
    00294
    00295             //
    00296             // Working set manager event.
    00297             //
    00298
    00299         case WorkingSetManagerEvent:
    00300
    00301             //
    00302             // Call the working set manager to trim working sets.
    00303             //
    00304
    00305             MmWorkingSetManager();
    00306             break;
    00307
    00308             //
    00309             // Illegal return status.
    00310             //
    00311
    00312         default:
    00313             KdPrint(("BALMGR: Illegal wait status, %lx =\n", Status));
    00314             break;
    00315         }
    00316
    00317     } while (TRUE);
    00318     return;
    00319 }

NTKERNELAPI VOID KeBoostCurrentThread | ( | VOID |  | ) |

Definition at line 154 of file waitsup.c.

References _KTHREAD::ApcState, _KTHREAD::BasePriority, _KTHREAD::DecrementCount, KeGetCurrentThread, KeSetPriorityThread(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), _KTHREAD::Priority, _KTHREAD::PriorityDecrement, _KAPC_STATE::Process, _KTHREAD::Quantum, ROUND_TRIP_DECREMENT_COUNT, and _KPROCESS::ThreadQuantum.

    00160                    :
    00161
    00162     This function boosts the priority of the current thread for one quantum,
    00163     then reduce the thread priority to the base priority of the thread.
    00164
    00165 Arguments:
    00166
    00167     None.
    00168
    00169 Return Value:
    00170
    00171     None.
    00172
    00173 --*/
    00174
    00175 {
    00176
    00177     KIRQL OldIrql;
    00178     PKTHREAD Thread;
    00179
    00180     //
    00181     // Get current thread address, raise IRQL to synchronization level, and
    00182     // lock the dispatcher database
    00183     //
    00184
    00185     Thread = KeGetCurrentThread();
    00186
    00187 redoboost:
    00188     KiLockDispatcherDatabase(&OldIrql);
    00189
    00190     //
    00191     // If a priority boost is not already active for the current thread
    00192     // and the thread priority is less than 14, then boost the thread
    00193     // priority to 14 and give the thread a large quantum. Otherwise,
    00194     // if a priority boost is active, then decrement the round trip
    00195     // count. If the count goes to zero, then release the dispatcher
    00196     // database lock, lower the thread priority to the base priority,
    00197     // and then attempt to boost the priority again. This will give
    00198     // other threads a chance to run. If the count does not reach zero,
    00199     // then give the thread another large qunatum.
    00200     //
    00201     // If the thread priority is above 14, then no boost is applied.
    00202     //
    00203
    00204     if ((Thread->PriorityDecrement == 0) && (Thread->Priority < 14)) {
    00205         Thread->PriorityDecrement = 14 - Thread->BasePriority;
    00206         Thread->DecrementCount = ROUND_TRIP_DECREMENT_COUNT;
    00207         Thread->Priority = 14;
    00208         Thread->Quantum = Thread->ApcState.Process->ThreadQuantum * 2;
    00209
    00210     } else if (Thread->PriorityDecrement != 0) {
    00211         Thread->DecrementCount -= 1;
    00212         if (Thread->DecrementCount == 0) {
    00213             KiUnlockDispatcherDatabase(OldIrql);
    00214             KeSetPriorityThread(Thread, Thread->BasePriority);
    00215             goto redoboost;
    00216
    00217         } else {
    00218             Thread->Quantum = Thread->ApcState.Process->ThreadQuantum * 2;
    00219         }
    00220     }
    00221
    00222     KiUnlockDispatcherDatabase(OldIrql);
    00223     return;
    00224 }

VOID KeBoostPriorityThread | ( | IN PKTHREAD | Thread,
|  | IN KPRIORITY | Increment
| ) |

Definition at line 459 of file thredobj.c.

References ASSERT, DISPATCH_LEVEL, Increment, KiBoostPriorityThread, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by ExpWaitForResourceDdk(), NtReadFile(), NtSetInformationProcess(), and VdmDispatchInterrupts().

    00466                    :
    00467
    00468     This function boosts the priority of the specified thread using the
    00469     same algorithm used when a thread gets a boost from a wait operation.
    00470
    00471 Arguments:
    00472
    00473     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00474
    00475     Increment - Supplies the priority increment that is to be applied to
    00476         the thread's priority.
    00477
    00478 Return Value:
    00479
    00480     None.
    00481
    00482 --*/
    00483
    00484 {
    00485
    00486     KIRQL OldIrql;
    00487
    00488     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00489
    00490     //
    00491     // Raise IRQL to dispatcher level and lock dispatcher database.
    00492     //
    00493
    00494     KiLockDispatcherDatabase(&OldIrql);
    00495
    00496     //
    00497     // If the thread does not run at a realtime priority level, then boost
    00498     // the thread priority.
    00499     //
    00500
    00501     if (Thread->Priority < LOW_REALTIME_PRIORITY) {
    00502         KiBoostPriorityThread(Thread, Increment);
    00503     }
    00504
    00505     //
    00506     // Unlock dispatcher database and lower IRQL to its previous
    00507     // value.
    00508     //
    00509
    00510     KiUnlockDispatcherDatabase(OldIrql);
    00511     return;
    00512 }

NTKERNELAPI DECLSPEC_NORETURN VOID NTAPI KeBugCheck | ( | IN ULONG | BugCheckCode | ) |

Definition at line 218 of file cmwraper.c.

References exit, and KeBugCheckEx().

Referenced by CheckPool(), ExAllocatePool(), ExAllocatePoolWithQuota(), ExAllocatePoolWithQuotaTag(), ExFreePool(), ExpFindCurrentThread(), InitializePool(), IoBuildPartialMdl(), IopAssignNetworkDriveLetter(), KeDetachProcess(), KePhase0DeleteIoMap(), KeSetAffinityThread(), KeUnstackDetachProcess(), KeWaitForMultipleObjects(), Ki386CheckDivideByZeroTrap(), KiDataBusError(), KiEspToTrapFrame(), KiGetVectorInfo(), KiInitializeGDT(), KiInitializeKernel(), KiInstructionBusError(), KiMachineCheck(), KiMemoryFault(), KiSystemServiceHandler(), LfsGetLbcb(), MiInitMachineDependent(), MiMapImageHeaderInHyperSpace(), MiMapPageInHyperSpace(), MiMapPageToZeroInHyperSpace(), PsInitSystem(), PspExitNormalApc(), PspExitThread(), PspProcessDelete(), PspSystemThreadStartup(), PspThreadDelete(), SeDefaultObjectMethod(), SeInitSystem(), SepAuditFailed(), SepDeReferenceLogonSession(), and xHalIoAssignDriveLetters().

    00221 {
    00222     printf("BugCheck: code = %08lx\n", BugCheckCode);
    00223     exit(1);
    00224 }

NTKERNELAPI DECLSPEC_NORETURN VOID KeBugCheckEx | ( | IN ULONG | BugCheckCode,
|  | IN ULONG_PTR | BugCheckParameter1,
|  | IN ULONG_PTR | BugCheckParameter2,
|  | IN ULONG_PTR | BugCheckParameter3,
|  | IN ULONG_PTR | BugCheckParameter4
| ) |

Definition at line 428 of file bugcheck.c.

References Buffer, DATA_BUS_ERROR, DbgPrint, ExPoolCodeEnd, ExPoolCodeStart, FALSE, HalRebootRoutine, HalReturnToFirmware(), HIGH_LEVEL, INBV_DISPLAY_STRING_FILTER, InbvAcquireDisplayOwnership(), InbvDisplayString(), InbvEnableDisplayString(), InbvInstallDisplayStringFilter(), InbvIsBootDriverInstalled(), InbvResetDisplay(), InbvSetScrollRegion(), InbvSetTextColor(), InbvSolidColorFill(), IoWriteCrashDump(), IPI_FREEZE, IRQL_NOT_LESS_OR_EQUAL, IS_SYSTEM_ADDRESS, KdDebuggerDataBlock, KdDebuggerEnabled, KdDebuggerNotPresent, KdInitSystem(), KdPitchDebugger, KeActiveProcessors, KeBugCheckCount, KeBugCheckUnicodeToAnsi(), KeGetBugMessageText(), KeGetCurrentPrcb, KeGetCurrentThread, KeRaiseIrql(), KeStallExecutionProcessor(), KiBugCheckData, KiBugCheckDebugBreak(), KiBugCheckDriver, KiDisableInterrupts(), KiDumpParameterImages(), KiHardwareTrigger, KiIpiSend(), KiPcToFileHeader(), KiSaveProcessorControlState(), KiScanBugCheckCallbackList(), KMODE_EXCEPTION_NOT_HANDLED, MmIsHydraAddress(), MmIsSpecialPoolAddressFree(), MmLocateUnloadedDriver(), MmPoolCodeEnd, MmPoolCodeStart, MmPteCodeEnd, MmPteCodeStart, MmSpecialPoolEnd, MmSpecialPoolStart, NULL, POWER_FAILURE_SIMULATE, sprintf(), _KTHREAD::Teb, TRUE, and UNEXPECTED_KERNEL_MODE_TRAP.

Referenced by CmBootLastKnownGood(), CmGetSystemControlValues(), CmGetSystemDriverList(), CmInitSystem1(), CmpCheckLockExceptionFilter(), CmpHiveRootSecurityDescriptor(), CmpInitializeCache(), CmpInitializeHiveList(), CmpInitializeSystemHive(), CmpReleaseGlobalQuota(), CmpSecurityMethod(), CmpWorker(), DrvDriverFailure(), ExAllocatePoolSanityChecks(), ExFreePoolSanityChecks(), ExFreePoolWithTag(), ExInitializeRegion(), ExInterlockedExtendRegion(), ExpCheckForWorker(), ExpSystemErrorHandler(), ExpWorkerThread(), ExReleaseResourceLite(), ExUnlockHandleTableEntry(), FsRtlWorkerThread(), HvRefreshHive(), InitializePool(), IoAssignResources(), IoBuildPoDeviceNotifyList(), IoCancelIrp(), IoInitSystem(), IopDestroyDeviceNode(), IopDriverCorrectnessThrowBugCheck(), IopEnumerateDevice(), IopfCallDriver(), IopFreeIrp(), IopInitializeBootDrivers(), IopMarkBootPartition(), IopMountVolume(), IopProcessNewDeviceNode(), IopProcessRelation(), IopStartAndEnumerateDevice(), IoReportResourceForDetection(), IoReportResourceUsage(), IovBuildAsynchronousFsdRequest(), IovBuildDeviceIoControlRequest(), IovCallDriver(), IovCompleteRequest(), IovFreeIrpPrivate(), IovInitializeTimer(), IovpCompleteRequest(), IovSpecialIrpCallDriver(), KdpCauseBugCheck(), KeAttachProcess(), KeBugCheck(), KeBusError(), KeCheckForTimer(), KeForceAttachProcess(), KeRemoveQueue(), KeRundownThread(), KeStackAttachProcess(), KfSanityCheckLowerIrql(), KfSanityCheckRaiseIrql(), KiDeliverApc(), KiDispatchException(), KiEmulateFloat(), KiGeneralExceptions(), KiIA32ExceptionNoDevice(), KiIA32ExceptionPanic(), KiIA32InterceptInstruction(), KiInitializeKernel(), KiMemoryFault(), KiNatExceptions(), KiRequestSoftwareInterrupt(), MiAddMdlTracker(), MiAllocatePoolPages(), MiAllocateSpecialPool(), MiCheckSessionPoolAllocations(), MiCleanSection(), MiCloneProcessAddressSpace(), MiConvertToLoaderVirtual(), MiDecrementCloneBlockReference(), MiDecrementReferenceCount(), MiDecrementShareCount(), MiDeletePte(), MiDeleteSystemPagableVm(), MiEliminateWorkingSetEntry(), MiEnsureAvailablePageOrWait(), MiEnsureAvailablePagesInFreeDescriptor(), MiFreeMdlTracker(), MiFreePoolPages(), MiFreeSessionSpaceMap(), MiGetNextPhysicalPage(), MiHandleForkTransitionPte(), MiInitializeCopyOnWritePfn(), MiInitializePfn(), MiInitializeReadInProgressPfn(), MiInitializeTransitionPfn(), MiInitMachineDependent(), MiInsertPageInList(), MiInsertStandbyListAtFront(), MiLocateWsle(), MiLookupWsleHashIndex(), MiMakeOutswappedPageResident(), MiMakeSystemAddressValid(), MiMakeSystemAddressValidPfn(), MiMakeSystemAddressValidPfnSystemWs(), MiMakeSystemAddressValidPfnWs(), MiReleaseSystemPtes(), MiRemoveFromSystemSpace(), MiRemovePageByColor(), MiRemovePageFromList(), MiRemovePteTracker(), MiRemoveWsle(), MiReserveSystemPtes(), MiReserveSystemPtes2(), MiResolveMappedFileFault(), MiUnlinkPageFromList(), MiVerifyingDriverUnloading(), MiWaitForInPageComplete(), MmAccessFault(), MmCleanProcessAddressSpace(), MmFreeLoaderBlock(), MmFreeSpecialPool(), MmInPageKernelStack(), MmLockPagableDataSection(), MmMapViewInSystemCache(), MmPurgeSection(), MmUnloadSystemImage(), MmUnlockCachedPage(), MmUnlockPages(), MmZeroPageThread(), MxGetNextPage(), NtClose(), NtNotifyChangeMultipleKeys(), NtUserInitialize(), PsLocateSystemDll(), PspExitThread(), PspInitializeSystemDll(), PspInitPhase0(), PspUnhandledExceptionInSystemThread(), VerifierExAcquireFastMutex(), VerifierExAcquireFastMutexUnsafe(), VerifierExAcquireResourceExclusive(), VerifierExReleaseFastMutex(), VerifierExReleaseFastMutexUnsafe(), VerifierExReleaseResource(), VerifierExTryToAcquireFastMutex(), VerifierFreeTrackedPool(), VerifierKeReleaseSpinLock(), VerifierMapIoSpace(), VerifierMapLockedPages(), VerifierMapLockedPagesSpecifyCache(), VerifierProbeAndLockPages(), VerifierProbeAndLockProcessPages(), VerifierProbeAndLockSelectedPages(), VerifierSetEvent(), VerifierUnlockPages(), VerifierUnmapIoSpace(), VerifierUnmapLockedPages(), ViReleasePoolAllocation(), xHalAssignSlotResources(), and xHalTranslateBusAddress().

    00438                    :
    00439
    00440     This function crashes the system in a controlled manner.
    00441
    00442 Arguments:
    00443
    00444     BugCheckCode - Supplies the reason for the bug check.
    00445
    00446     BugCheckParameter1-4 - Supplies additional bug check information
    00447
    00448 Return Value:
    00449
    00450     None.
    00451
    00452 --*/
    00453
    00454 {
    00455     UCHAR Buffer[100];
    00456     ULONG_PTR BugCheckParameters[4];
    00457     CONTEXT ContextSave;
    00458     ULONG PssMessage;
    00459     PCHAR HardErrorCaption;
    00460     PCHAR HardErrorMessage;
    00461     KIRQL OldIrql;
    00462     PKTRAP_FRAME TrapInformation;
    00463     PVOID ExecutionAddress;
    00464     PVOID ImageBase;
    00465     PVOID VirtualAddress;
    00466     PLDR_DATA_TABLE_ENTRY DataTableEntry;
    00467     UCHAR AnsiBuffer[32];
    00468     PKTHREAD Thread;
    00469     BOOLEAN InKernelOrHal;
    00470     BOOLEAN DontCare;
    00471
    00472 #if !defined(NT_UP)
    00473
    00474     ULONG TargetSet;
    00475
    00476 #endif
    00477     BOOLEAN hardErrorCalled;
    00478
    00479     //
    00480     // Try to simulate a power failure for Cluster testing
    00481     //
    00482
    00483     if (BugCheckCode == POWER_FAILURE_SIMULATE) {
    00484         KiScanBugCheckCallbackList();
    00485         HalReturnToFirmware(HalRebootRoutine);
    00486     }
    00487
    00488     //
    00489     // Capture the callers context as closely as possible into the debugger's
    00490     // processor state area of the Prcb.
    00491     //
    00492     // N.B. There may be some prologue code that shuffles registers such that
    00493     //      they get destroyed.
    00494     //
    00495
    00496 #if defined(i386)
    00497     KiSetHardwareTrigger();
    00498 #else
    00499     KiHardwareTrigger = 1;
    00500 #endif
    00501
    00502     RtlCaptureContext(&KeGetCurrentPrcb()->ProcessorState.ContextFrame);
    00503     KiSaveProcessorControlState(&KeGetCurrentPrcb()->ProcessorState);
    00504
    00505     //
    00506     // This is necessary on machines where the virtual unwind that happens
    00507     // during KeDumpMachineState() destroys the context record.
    00508     //
    00509
    00510     ContextSave = KeGetCurrentPrcb()->ProcessorState.ContextFrame;
    00511
    00512     //
    00513     // If we are called by hard error then we don't want to dump the
    00514     // processor state on the machine.
    00515     //
    00516     // We know that we are called by hard error because the bug check
    00517     // code will be FATAL_UNHANDLED_HARD_ERROR.  If this is so then the
    00518     // error status passed to harderr is the first parameter, and a pointer
    00519     // to the parameter array from hard error is passed as the second
    00520     // argument.
    00521     //
    00522     // The third argument is the OemCaption to be printed.
    00523     // The last argument is the OemMessage to be printed.
    00524     //
    00525
    00526     if (BugCheckCode == FATAL_UNHANDLED_HARD_ERROR) {
    00527
    00528         PULONG_PTR parameterArray;
    00529
    00530         hardErrorCalled = TRUE;
    00531
    00532         HardErrorCaption = (PCHAR)BugCheckParameter3;
    00533         HardErrorMessage = (PCHAR)BugCheckParameter4;
    00534         parameterArray = (PULONG_PTR)BugCheckParameter2;
    00535         BugCheckCode = (ULONG)BugCheckParameter1;
    00536         BugCheckParameter1 = parameterArray[0];
    00537         BugCheckParameter2 = parameterArray[1];
    00538         BugCheckParameter3 = parameterArray[2];
    00539         BugCheckParameter4 = parameterArray[3];
    00540
    00541     } else {
    00542
    00543         hardErrorCalled = FALSE;
    00544
    00545         switch (BugCheckCode) {
    00546
    00547             case IRQL_NOT_LESS_OR_EQUAL:
    00548
    00549                 ExecutionAddress = (PVOID)BugCheckParameter4;
    00550
    00551                 if (ExecutionAddress >= ExPoolCodeStart && ExecutionAddress < ExPoolCodeEnd) {
    00552                     BugCheckCode = DRIVER_CORRUPTED_EXPOOL;
    00553                 }
    00554                 else if (ExecutionAddress >= MmPoolCodeStart && ExecutionAddress < MmPoolCodeEnd) {
    00555                     BugCheckCode = DRIVER_CORRUPTED_MMPOOL;
    00556                 }
    00557                 else if (ExecutionAddress >= MmPteCodeStart && ExecutionAddress < MmPteCodeEnd) {
    00558                     BugCheckCode = DRIVER_CORRUPTED_SYSPTES;
    00559                 }
    00560                 else {
    00561                     ImageBase = KiPcToFileHeader (ExecutionAddress,
    00562                                                   &DataTableEntry,
    00563                                                   FALSE,
    00564                                                   &InKernelOrHal);
    00565                     if (InKernelOrHal == TRUE) {
    00566
    00567                         //
    00568                         // The kernel faulted at raised IRQL.  Quite often this
    00569                         // is a driver that has unloaded without deleting its
    00570                         // lookaside lists or other resources.  Or its resources
    00571                         // are marked pagable and shouldn't be.  Detect both
    00572                         // cases here and identify the offending driver
    00573                         // whenever possible.
    00574                         //
    00575
    00576                         VirtualAddress = (PVOID)BugCheckParameter1;
    00577
    00578                         ImageBase = KiPcToFileHeader (VirtualAddress,
    00579                                                       &DataTableEntry,
    00580                                                       TRUE,
    00581                                                       &InKernelOrHal);
    00582
    00583                         if (ImageBase != NULL) {
    00584                             KiBugCheckDriver = &DataTableEntry->BaseDllName;
    00585                             BugCheckCode = DRIVER_PORTION_MUST_BE_NONPAGED;
    00586                         }
    00587                         else {
    00588                             KiBugCheckDriver = MmLocateUnloadedDriver (VirtualAddress);
    00589                             if (KiBugCheckDriver != NULL) {
    00590                                 BugCheckCode = SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD;
    00591                             }
    00592                         }
    00593                     }
    00594                     else {
    00595                         BugCheckCode = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
    00596                     }
    00597                 }
    00598                 break;
    00599
    00600             case ATTEMPTED_WRITE_TO_READONLY_MEMORY:
    00601
    00602                 KiBugCheckDriver = NULL;
    00603                 TrapInformation = (PKTRAP_FRAME)BugCheckParameter3;
    00604
    00605                 //
    00606                 // Extract the execution address from the trap frame to
    00607                 // identify the component.
    00608                 //
    00609
    00610                 if (TrapInformation != NULL) {
    00611                     ExecutionAddress = (PVOID)PROGRAM_COUNTER (TrapInformation);
    00612                     ImageBase = KiPcToFileHeader (ExecutionAddress,
    00613                                                   &DataTableEntry,
    00614                                                   TRUE,
    00615                                                   &InKernelOrHal);
    00616
    00617                     if (ImageBase != NULL) {
    00618                         KiBugCheckDriver = &DataTableEntry->BaseDllName;
    00619                     }
    00620                 }
    00621
    00622                 break;
    00623
    00624             case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:
    00625
    00626                 ExecutionAddress = (PVOID)BugCheckParameter1;
    00627
    00628                 ImageBase = KiPcToFileHeader (ExecutionAddress,
    00629                                               &DataTableEntry,
    00630                                               TRUE,
    00631                                               &InKernelOrHal);
    00632
    00633                 if (ImageBase != NULL) {
    00634                     KiBugCheckDriver = &DataTableEntry->BaseDllName;
    00635                 }
    00636                 else {
    00637                     KiBugCheckDriver = MmLocateUnloadedDriver (ExecutionAddress);
    00638                 }
    00639
    00640                 BugCheckParameter4 = (ULONG_PTR)KiBugCheckDriver;
    00641
    00642                 break;
    00643
    00644             case DRIVER_USED_EXCESSIVE_PTES:
    00645
    00646                 DataTableEntry = (PLDR_DATA_TABLE_ENTRY)BugCheckParameter1;
    00647                 KiBugCheckDriver = &DataTableEntry->BaseDllName;
    00648
    00649                 break;
    00650
    00651             case PAGE_FAULT_IN_NONPAGED_AREA:
    00652
    00653                 ExecutionAddress = NULL;
    00654                 KiBugCheckDriver = NULL;
    00655
    00656                 VirtualAddress = (PVOID)BugCheckParameter1;
    00657
    00658                 TrapInformation = (PKTRAP_FRAME)BugCheckParameter3;
    00659
    00660                 //
    00661                 // Extract the execution address from the trap frame to
    00662                 // identify the component.
    00663                 //
    00664
    00665                 if (TrapInformation != NULL) {
    00666
    00667                     ExecutionAddress = (PVOID)PROGRAM_COUNTER (TrapInformation);
    00668                     BugCheckParameter3 = (ULONG_PTR)ExecutionAddress;
    00669
    00670                     KiPcToFileHeader (ExecutionAddress,
    00671                                       &DataTableEntry,
    00672                                       FALSE,
    00673                                       &InKernelOrHal);
    00674
    00675                     ImageBase = KiPcToFileHeader (ExecutionAddress,
    00676                                                   &DataTableEntry,
    00677                                                   TRUE,
    00678                                                   &DontCare);
    00679
    00680                     if (ImageBase != NULL) {
    00681                         KiBugCheckDriver = &DataTableEntry->BaseDllName;
    00682                     }
    00683                 }
    00684                 else {
    00685
    00686                     //
    00687                     // No trap frame, so no execution address either.
    00688                     //
    00689
    00690                     BugCheckParameter3 = 0;
    00691                 }
    00692
    00693                 Thread = KeGetCurrentThread();
    00694
    00695                 if ((VirtualAddress >= MmSpecialPoolStart) &&
    00696                     (VirtualAddress < MmSpecialPoolEnd)) {
    00697
    00698                     //
    00699                     // Update the bugcheck number so the administrator gets
    00700                     // useful feedback that enabling special pool has enabled
    00701                     // the system to locate the corruptor.
    00702                     //
    00703
    00704                     if (MmIsSpecialPoolAddressFree (VirtualAddress) == TRUE) {
    00705                         if (InKernelOrHal == TRUE) {
    00706                             BugCheckCode = PAGE_FAULT_IN_FREED_SPECIAL_POOL;
    00707                         }
    00708                         else {
    00709                             BugCheckCode = DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL;
    00710                         }
    00711                     }
    00712                     else {
    00713                         if (InKernelOrHal == TRUE) {
    00714                             BugCheckCode = PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
    00715                         }
    00716                         else {
    00717                             BugCheckCode = DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
    00718                         }
    00719                     }
    00720                 }
    00721                 else if ((ExecutionAddress == VirtualAddress) &&
    00722                         (MmIsHydraAddress (VirtualAddress) == TRUE) &&
    00723                         ((Thread->Teb == NULL) || (IS_SYSTEM_ADDRESS(Thread->Teb)))) {
    00724                     //
    00725                     // This is a driver reference to session space from a
    00726                     // worker thread.  Since the system process has no session
    00727                     // space this is illegal and the driver must be fixed.
    00728                     //
    00729
    00730                     BugCheckCode = TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE;
    00731                 }
    00732                 else {
    00733                     KiBugCheckDriver = MmLocateUnloadedDriver (VirtualAddress);
    00734                     if (KiBugCheckDriver != NULL) {
    00735                         BugCheckCode = DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS;
    00736                     }
    00737                 }
    00738
    00739                 break;
    00740
    00741             default:
    00742                 break;
    00743         }
    00744     }
    00745
    00746     if (KiBugCheckDriver != NULL) {
    00747         KeBugCheckUnicodeToAnsi (KiBugCheckDriver,
    00748                                  AnsiBuffer,
    00749                                  sizeof (AnsiBuffer));
    00750     }
    00751
    00752     KiBugCheckData[0] = BugCheckCode;
    00753     KiBugCheckData[1] = BugCheckParameter1;
    00754     KiBugCheckData[2] = BugCheckParameter2;
    00755     KiBugCheckData[3] = BugCheckParameter3;
    00756     KiBugCheckData[4] = BugCheckParameter4;
    00757
    00758     BugCheckParameters[0] = BugCheckParameter1;
    00759     BugCheckParameters[1] = BugCheckParameter2;
    00760     BugCheckParameters[2] = BugCheckParameter3;
    00761     BugCheckParameters[3] = BugCheckParameter4;
    00762
    00763     if (KdPitchDebugger == FALSE ) {
    00764         KdDebuggerDataBlock.SavedContext = (ULONG_PTR) &ContextSave;
    00765     }
    00766
    00767     //
    00768     // If the user manually crashed the machine, skips the DbgPrints and
    00769     // go to the crashdump.
    00770     // Trying to do DbgPrint causes us to reeeter the debugger which causes
    00771     // some problems.
    00772     //
    00773     // Otherwise, if the debugger is enabled, print out the information and
    00774     // stop.
    00775     //
    00776
    00777     if ((BugCheckCode != MANUALLY_INITIATED_CRASH) &&
    00778         (KdDebuggerEnabled)) {
    00779
    00780         DbgPrint("\n*** Fatal System Error: 0x%08lx\n"
    00781                  "                       (0x%p,0x%p,0x%p,0x%p)\n\n",
    00782                  BugCheckCode,
    00783                  BugCheckParameter1,
    00784                  BugCheckParameter2,
    00785                  BugCheckParameter3,
    00786                  BugCheckParameter4);
    00787
    00788         //
    00789         // If the debugger is not actually connected, or the user manually
    00790         // crashed the machine by typing .crash in the debugger, proceed to
    00791         // "blue screen" the system.
    00792         //
    00793         // The call to DbgPrint above will have set the state of
    00794         // KdDebuggerNotPresent if the debugger has become disconnected
    00795         // since the system was booted.
    00796         //
    00797
    00798         if (KdDebuggerNotPresent == FALSE) {
    00799
    00800             if (KiBugCheckDriver != NULL) {
    00801                 DbgPrint("The %s driver may be at fault.\n", AnsiBuffer);
    00802             }
    00803
    00804             if (hardErrorCalled != FALSE) {
    00805                 if (HardErrorCaption) {
    00806                     DbgPrint(HardErrorCaption);
    00807                 }
    00808                 if (HardErrorMessage) {
    00809                     DbgPrint(HardErrorMessage);
    00810                 }
    00811             }
    00812
    00813             KiBugCheckDebugBreak (DBG_STATUS_BUGCHECK_FIRST);
    00814         }
    00815     }
    00816
    00817     //
    00818     // Freeze execution of the system by disabling interrupts and looping.
    00819     //
    00820
    00821     KiDisableInterrupts();
    00822     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    00823
    00824     //
    00825     // Don't attempt to display message more than once.
    00826     //
    00827
    00828     if (InterlockedDecrement (&KeBugCheckCount) == 0) {
    00829
    00830 #if !defined(NT_UP)
    00831
    00832         //
    00833         // Attempt to get the other processors frozen now, but don't wait
    00834         // for them to freeze (in case someone is stuck).
    00835         //
    00836
    00837         TargetSet = KeActiveProcessors & ~KeGetCurrentPrcb()->SetMember;
    00838         if (TargetSet != 0) {
    00839             KiIpiSend((KAFFINITY) TargetSet, IPI_FREEZE);
    00840
    00841             //
    00842             // Give the other processors one second to flush their data caches.
    00843             //
    00844             // N.B. This cannot be synchronized since the reason for the bug
    00845             //      may be one of the other processors failed.
    00846             //
    00847
    00848             KeStallExecutionProcessor(1000 * 1000);
    00849         }
    00850
    00851 #endif
    00852
    00853         //
    00854         // Enable InbvDisplayString calls to make it through to bootvid driver.
    00855         //
    00856
    00857         if (InbvIsBootDriverInstalled()) {
    00858
    00859             InbvAcquireDisplayOwnership();
    00860
    00861             InbvResetDisplay();
    00862             InbvSolidColorFill(0,0,639,479,4); // make the screen blue
    00863             InbvSetTextColor(15);
    00864             InbvInstallDisplayStringFilter((INBV_DISPLAY_STRING_FILTER)NULL);
    00865             InbvEnableDisplayString(TRUE);     // enable display string
    00866             InbvSetScrollRegion(0,0,639,479);  // set to use entire screen
    00867         }
    00868
    00869         if (!hardErrorCalled) {
    00870             sprintf((char *)Buffer,
    00871                     "\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n",
    00872                     BugCheckCode,
    00873                     BugCheckParameter1,
    00874                     BugCheckParameter2,
    00875                     BugCheckParameter3,
    00876                     BugCheckParameter4
    00877                     );
    00878             InbvDisplayString((char *)Buffer);
    00879
    00880             KeGetBugMessageText(BugCheckCode, NULL);
    00881             InbvDisplayString("\n");
    00882
    00883             if (KiBugCheckDriver != NULL) {
    00884
    00885                 //
    00886                 // Output the driver name.
    00887                 //
    00888
    00889                 KeGetBugMessageText(BUGCODE_ID_DRIVER, NULL);
    00890                 InbvDisplayString(AnsiBuffer);
    00891                 InbvDisplayString("\n");
    00892             }
    00893
    00894         } else {
    00895             if (HardErrorCaption) {
    00896                 InbvDisplayString(HardErrorCaption);
    00897             }
    00898             if (HardErrorMessage) {
    00899                 InbvDisplayString(HardErrorMessage);
    00900             }
    00901         }
    00902
    00903         //
    00904         // Process the bug check callback list.
    00905         //
    00906
    00907         KiScanBugCheckCallbackList();
    00908
    00909         //
    00910         // If the debugger is not enabled, then dump the machine state and
    00911         // attempt to enable the debugger.
    00912         //
    00913
    00914         if (!hardErrorCalled) {
    00915
    00916             KiDumpParameterImages(
    00917                 (char *)Buffer,
    00918                 BugCheckParameters,
    00919                 4,
    00920                 KeBugCheckUnicodeToAnsi);
    00921
    00922         }
    00923
    00924         if (KdDebuggerEnabled == FALSE && KdPitchDebugger == FALSE ) {
    00925             KdInitSystem(NULL, FALSE);
    00926
    00927         } else {
    00928             InbvDisplayString("\n");
    00929         }
    00930
    00931         //
    00932         // Write a crash dump and optionally reboot if the system has been
    00933         // so configured.
    00934         //
    00935
    00936         KeGetCurrentPrcb()->ProcessorState.ContextFrame = ContextSave;
    00937
    00938         if (!IoWriteCrashDump(BugCheckCode,
    00939                               BugCheckParameter1,
    00940                               BugCheckParameter2,
    00941                               BugCheckParameter3,
    00942                               BugCheckParameter4,
    00943                               &ContextSave
    00944                               )) {
    00945             //
    00946             // If no crashdump take, display the PSS message.
    00947             //
    00948
    00949             switch ( BugCheckCode ) {
    00950
    00951                 case IRQL_NOT_LESS_OR_EQUAL:
    00952                 case DRIVER_IRQL_NOT_LESS_OR_EQUAL:
    00953                 case DRIVER_CORRUPTED_EXPOOL:
    00954                 case DRIVER_CORRUPTED_MMPOOL:
    00955                 case DRIVER_PORTION_MUST_BE_NONPAGED:
    00956                 case SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD:
    00957                     PssMessage = BUGCODE_PSS_MESSAGE_A;
    00958                     break;
    00959
    00960                 case KMODE_EXCEPTION_NOT_HANDLED:
    00961                     PssMessage = BUGCODE_PSS_MESSAGE_1E;
    00962                     break;
    00963
    00964                 case FAT_FILE_SYSTEM:
    00965                 case NTFS_FILE_SYSTEM:
    00966                     PssMessage = BUGCODE_PSS_MESSAGE_23;
    00967                     break;
    00968
    00969                 case DATA_BUS_ERROR:
    00970                     PssMessage = BUGCODE_PSS_MESSAGE_2E;
    00971                     break;
    00972
    00973                 case NO_MORE_SYSTEM_PTES:
    00974                     PssMessage = BUGCODE_PSS_MESSAGE_3F;
    00975                     break;
    00976
    00977                 case INACCESSIBLE_BOOT_DEVICE:
    00978                     PssMessage = BUGCODE_PSS_MESSAGE_7B;
    00979                     break;
    00980
    00981                 case UNEXPECTED_KERNEL_MODE_TRAP:
    00982                     PssMessage = BUGCODE_PSS_MESSAGE_7F;
    00983                     break;
    00984
    00985                 case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE:
    00986                     PssMessage = BUGCODE_PSS_MESSAGE_SIGNATURE;
    00987                     break;
    00988
    00989                 case ACPI_BIOS_ERROR:
    00990                     PssMessage = BUGCODE_PSS_MESSAGE_A5;
    00991                     break;
    00992
    00993                 case ACPI_BIOS_FATAL_ERROR:
    00994                     PssMessage = ACPI_BIOS_FATAL_ERROR;
    00995                     break;
    00996
    00997                 default:
    00998                     PssMessage = BUGCODE_PSS_MESSAGE;
    00999                     break;
    01000                 }
    01001
    01002             KeGetBugMessageText(PssMessage, NULL);
    01003         }
    01004     }
    01005
    01006     //
    01007     // Attempt to enter the kernel debugger.
    01008     //
    01009
    01010     KiBugCheckDebugBreak (DBG_STATUS_BUGCHECK_SECOND);
    01011     return;
    01012 }

NTKERNELAPI BOOLEAN KeCancelTimer | ( | IN | PKTIMER | ) |

Definition at line 157 of file timerobj.c.

References ASSERT, ASSERT_TIMER, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiRemoveTreeTimer, and KiUnlockDispatcherDatabase().

Referenced by ExpDeleteTimer(), ExTimerRundown(), NtCancelTimer(), NtSetTimer(), and Win32kNtUserCleanup().

    00163                    :
    00164
    00165     This function cancels a timer that was previously set to expire at
    00166     a specified time. If the timer is not currently set, then no operation
    00167     is performed. Canceling a timer does not set the state of the timer to
    00168     Signaled.
    00169
    00170 Arguments:
    00171
    00172     Timer - Supplies a pointer to a dispatcher object of type timer.
    00173
    00174 Return Value:
    00175
    00176     A boolean value of TRUE is returned if the the specified timer was
    00177     currently set. Else a value of FALSE is returned.
    00178
    00179 --*/
    00180
    00181 {
    00182
    00183     BOOLEAN Inserted;
    00184     KIRQL OldIrql;
    00185
    00186     ASSERT_TIMER(Timer);
    00187     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00188
    00189     //
    00190     // Raise IRQL to dispatcher level, lock the dispatcher database, and
    00191     // capture the timer inserted status. If the timer is currently set,
    00192     // then remove it from the timer list.
    00193     //
    00194
    00195     KiLockDispatcherDatabase(&OldIrql);
    00196     Inserted = Timer->Header.Inserted;
    00197     if (Inserted != FALSE) {
    00198         KiRemoveTreeTimer(Timer);
    00199     }
    00200
    00201     //
    00202     // Unlock the dispatcher database, lower IRQL to its previous value, and
    00203     // return boolean value that signifies whether the timer was set of not.
    00204     //
    00205
    00206     KiUnlockDispatcherDatabase(OldIrql);
    00207     return Inserted;
    00208 }

PVOID KeCheckForTimer | ( | IN PVOID | p,
|  | IN ULONG | Size
| ) |

Definition at line 467 of file timerobj.c.

References BlockSize, _KDPC::DeferredRoutine, _KTIMER::Dpc, End, Index, KeBugCheckEx(), KiLockDispatcherDatabase, KiTimerTableListHead, KiUnlockDispatcherDatabase(), NULL, Start, and TIMER_TABLE_SIZE.

Referenced by ExFreePoolSanityChecks(), MmUnloadSystemImage(), and VerifierKeInitializeTimerEx().

    00473                    :
    00474
    00475     This function is used for debugging by checking all timers
    00476     to see if any is in the memory block passed.  If so, the
    00477     system stops at a debug breakpoint.
    00478
    00479 Arguments:
    00480
    00481     MemoryBlock - Base address to check for timer
    00482
    00483     BlockSize - Size (in bytes) to check in memory block
    00484
    00485 Return Value:
    00486
    00487     The address of the currently active timer.
    00488
    00489 --*/
    00490 {
    00491     ULONG Index;
    00492     PLIST_ENTRY ListHead;
    00493     PLIST_ENTRY NextEntry;
    00494     KIRQL OldIrql;
    00495     PKTIMER Timer;
    00496     PUCHAR Address;
    00497     PUCHAR Start;
    00498     PUCHAR End;
    00499
    00500     //
    00501     // Compute the ending memory location.
    00502     //
    00503
    00504     Start = (PUCHAR)BlockStart;
    00505     End = Start + BlockSize;
    00506
    00507     //
    00508     // Raise IRQL to dispatcher level and lock dispatcher database.
    00509     //
    00510
    00511     KiLockDispatcherDatabase(&OldIrql);
    00512
    00513     //
    00514     // Run the entire timer database and check for any timers in
    00515     // the memory block
    00516     //
    00517
    00518     Index = 0;
    00519     do {
    00520         ListHead = &KiTimerTableListHead[Index];
    00521         NextEntry = ListHead->Flink;
    00522         while (NextEntry != ListHead) {
    00523             Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
    00524             Address = (PUCHAR)Timer;
    00525             NextEntry = NextEntry->Flink;
    00526
    00527             //
    00528             // Check this timer object is not in the range.
    00529             // In each of the following, we check that the object
    00530             // does not overlap the range, for example, if the timer
    00531             // object (in this first check), starts one dword before
    00532             // the range being checked, we have an overlap and should
    00533             // stop.
    00534             //
    00535
    00536             if ((Address > (Start - sizeof(KTIMER))) &&
    00537                 (Address < End)) {
    00538                 KeBugCheckEx(TIMER_OR_DPC_INVALID,
    00539                              0x0,
    00540                              (ULONG_PTR)Address,
    00541                              (ULONG_PTR)Start,
    00542                              (ULONG_PTR)End);
    00543             }
    00544
    00545             if (Timer->Dpc) {
    00546
    00547                 //
    00548                 // Check the timer's DPC object isn't in the range.
    00549                 //
    00550
    00551                 Address = (PUCHAR)Timer->Dpc;
    00552                 if ((Address > (Start - sizeof(KDPC))) &&
    00553                     (Address < End)) {
    00554                     KeBugCheckEx(TIMER_OR_DPC_INVALID,
    00555                                  0x1,
    00556                                  (ULONG_PTR)Address,
    00557                                  (ULONG_PTR)Start,
    00558                                  (ULONG_PTR)End);
    00559                 }
    00560
    00561                 //
    00562                 // Check the timer's DPC routine is not in the range.
    00563                 //
    00564
    00565                 Address = (PUCHAR)Timer->Dpc->DeferredRoutine;
    00566                 if (Address >= Start && Address < End) {
    00567                     KeBugCheckEx(TIMER_OR_DPC_INVALID,
    00568                                  0x2,
    00569                                  (ULONG_PTR)Address,
    00570                                  (ULONG_PTR)Start,
    00571                                  (ULONG_PTR)End);
    00572                 }
    00573             }
    00574         }
    00575
    00576         Index += 1;
    00577     } while(Index < TIMER_TABLE_SIZE);
    00578
    00579
    00580     //
    00581     // Unlock the dispatcher database and lower IRQL to its previous value
    00582     //
    00583
    00584     KiUnlockDispatcherDatabase(OldIrql);
    00585     return NULL;
    00586 }
    }

VOID KeClearTimer | ( | IN PKTIMER | Timer | ) |

Definition at line 124 of file timerobj.c.

References ASSERT_TIMER.

    00130                    :
    00131
    00132     This function clears the signal state of an timer object.
    00133
    00134 Arguments:
    00135
    00136     Event - Supplies a pointer to a dispatcher object of type timer.
    00137
    00138 Return Value:
    00139
    00140     None.
    00141
    00142 --*/
    00143
    00144 {
    00145
    00146     ASSERT_TIMER(Timer);
    00147
    00148     //
    00149     // Clear signal state of timer object.
    00150     //
    00151
    00152     Timer->Header.SignalState = 0;
    00153     return;
    00154 }

KAFFINITY KeConfineThread | ( | VOID |  | ) |

Definition at line 515 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and _KTHREAD::NextProcessor.

    00521                    :
    00522
    00523     This function confines the execution of the current thread to the current
    00524     processor.
    00525
    00526 Arguments:
    00527
    00528     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00529
    00530 Return Value:
    00531
    00532     The previous affinity value.
    00533
    00534 --*/
    00535
    00536 {
    00537
    00538     KAFFINITY Affinity;
    00539     KIRQL OldIrql;
    00540     PKTHREAD Thread;
    00541
    00542     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00543
    00544     //
    00545     // Raise IRQL to dispatcher level and lock dispatcher database.
    00546     //
    00547
    00548     Thread = KeGetCurrentThread();
    00549     KiLockDispatcherDatabase(&OldIrql);
    00550
    00551     //
    00552     // Capture the current affinity and compute new affinity value by
    00553     // shifting a one bit left by the current processor number.
    00554     //
    00555
    00556     Affinity = Thread->Affinity;
    00557     Thread->Affinity = (KAFFINITY)(1 << Thread->NextProcessor);
    00558
    00559     //
    00560     // Unlock dispatcher database and lower IRQL to its previous
    00561     // value.
    00562     //
    00563
    00564     KiUnlockDispatcherDatabase(OldIrql);
    00565
    00566     //
    00567     // Return the previous affinity value.
    00568     //
    00569
    00570     return Affinity;
    00571 }

NTKERNELAPI BOOLEAN KeConnectInterrupt | ( | IN PKINTERRUPT | Interrupt | ) |

Definition at line 154 of file alpha/intobj.c.

References CHAR, _KINTERRUPT::DispatchAddress, _KINTERRUPT::DispatchCode, FALSE, HalEnableSystemInterrupt(), HIGH_LEVEL, _KINTERRUPT::InterruptListEntry, KeLowerIrql(), KeNumberProcessors, KeRaiseIrql(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KiChainedDispatch(), KiFloatingDispatch(), KiInterruptDispatchRaise(), KiInterruptDispatchSame(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), max, _KINTERRUPT::Mode, _KINTERRUPT::ShareVector, SYNCH_LEVEL, and TRUE.

Referenced by IoConnectInterrupt().

    00160                    :
    00161
    00162     This function connects an interrupt object to the interrupt vector
    00163     specified by the interrupt object. If the interrupt object is already
    00164     connected, or an attempt is made to connect to an interrupt that cannot
    00165     be connected, then a value of FALSE is returned. Else the specified
    00166     interrupt object is connected to the interrupt vector, the connected
    00167     state is set to TRUE, and TRUE is returned as the function value.
    00168
    00169 Arguments:
    00170
    00171     Interrupt - Supplies a pointer to a control object of type interrupt.
    00172
    00173 Return Value:
    00174
    00175     If the interrupt object is already connected or an attempt is made to
    00176     connect to an interrupt vector that cannot be connected, then a value
    00177     of FALSE is returned. Else a value of TRUE is returned.
    00178
    00179 --*/
    00180
    00181 {
    00182
    00183     BOOLEAN Connected;
    00184     PKINTERRUPT Interruptx;
    00185     KIRQL Irql;
    00186     CHAR Number;
    00187     KIRQL OldIrql;
    00188     ULONG Vector;
    00189
    00190     //
    00191     // If the interrupt object is already connected, the interrupt vector
    00192     // number is invalid, an attempt is being made to connect to a vector
    00193     // that cannot be connected, the interrupt request level is invalid,
    00194     // the processor number is invalid, of the interrupt vector is less
    00195     // than or equal to the highest level and it not equal to the specified
    00196     // IRQL, then do not connect the interrupt object. Else connect interrupt
    00197     // object to the specified vector and establish the proper interrupt
    00198     // dispatcher.
    00199     //
    00200
    00201     Connected = FALSE;
    00202     Irql = Interrupt->Irql;
    00203     Number = Interrupt->Number;
    00204     Vector = Interrupt->Vector;
    00205     if (((Vector >= MAXIMUM_VECTOR) || (Irql > HIGH_LEVEL) ||
    00206        ((Vector <= HIGH_LEVEL) &&
    00207        (((1 << Vector & PCR->ReservedVectors) != 0))) ||
    00208        (Number >= KeNumberProcessors)) == FALSE) {
    00209
    00210         //
    00211         // Set system affinity to the specified processor.
    00212         //
    00213
    00214         KeSetSystemAffinityThread((KAFFINITY)(1 << Number));
    00215
    00216         //
    00217         // Raise IRQL to dispatcher level and lock dispatcher database.
    00218         //
    00219
    00220         KiLockDispatcherDatabase(&OldIrql);
    00221
    00222         //
    00223         // If the specified interrupt vector is not connected, then
    00224         // connect the interrupt vector to the interrupt object dispatch
    00225         // code, establish the dispatcher address, and set the new
    00226         // interrupt mode and enable masks. Else if the interrupt is
    00227         // already chained, then add the new interrupt object at the end
    00228         // of the chain. If the interrupt vector is not chained, then
    00229         // start a chain with the previous interrupt object at the front
    00230         // of the chain. The interrupt mode of all interrupt objects in
    00231         // a chain must be the same.
    00232         //
    00233
    00234         if (Interrupt->Connected == FALSE) {
    00235             if ( PCR->InterruptRoutine[Vector] ==
    00236                  (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode) ) {
    00237                 Connected = TRUE;
    00238                 Interrupt->Connected = TRUE;
    00239                 if (Interrupt->FloatingSave) {
    00240                     Interrupt->DispatchAddress = KiFloatingDispatch;
    00241
    00242                 } else {
    00243                     if (Interrupt->Irql == Interrupt->SynchronizeIrql) {
    00244                         Interrupt->DispatchAddress =
    00245                                     (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame;
    00246                     } else {
    00247                         Interrupt->DispatchAddress =
    00248                                     (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise;
    00249                     }
    00250                 }
    00251
    00252                 PCR->InterruptRoutine[Vector] =
    00253                             (PKINTERRUPT_ROUTINE)(&Interrupt->DispatchCode);
    00254
    00255                 HalEnableSystemInterrupt(Vector, Irql, Interrupt->Mode);
    00256
    00257             } else {
    00258                 Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector],
    00259                                                KINTERRUPT,
    00260                                                DispatchCode[0]);
    00261
    00262                 if (Interrupt->Mode == Interruptx->Mode) {
    00263                     Connected = TRUE;
    00264                     Interrupt->Connected = TRUE;
    00265                     ASSERT (Irql <= KiSynchIrql);
    00266                     if (Interruptx->DispatchAddress != KiChainedDispatch) {
    00267                         InitializeListHead(&Interruptx->InterruptListEntry);
    00268                         Interruptx->DispatchAddress = KiChainedDispatch;
    00269                     }
    00270
    00271                     InsertTailList(&Interruptx->InterruptListEntry,
    00272                                    &Interrupt->InterruptListEntry);
    00273                 }
    00274             }
    00275         }
    00276
    00277         //
    00278         // Unlock dispatcher database and lower IRQL to its previous value.
    00279         //
    00280
    00281         KiUnlockDispatcherDatabase(OldIrql);
    00282
    00283         //
    00284         // Set system affinity back to the original value.
    00285         //
    00286
    00287         KeRevertToUserAffinityThread();
    00288     }
    00289
    00290     //
    00291     // Return whether interrupt was connected to the specified vector.
    00292     //
    00293
    00294     return Connected;
    00295 }

VOID KeContextFromKframes | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN OUT PCONTEXT | ContextFrame
| ) |

Definition at line 104 of file alpha/exceptn.c.

References CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, KeGetCurrentThread, KernelMode, and KiBreakPoints.

Referenced by Ke386SetIOPL(), KiDispatchException(), KiInitializeUserApc(), KiSaveProcessorState(), and PspGetContext().

    00112                    :
    00113
    00114     This routine moves the selected contents of the specified trap and exception
    00115     frames into the specified context frame according to the specified context
    00116     flags.
    00117
    00118 Arguments:
    00119
    00120     TrapFrame - Supplies a pointer to a trap frame from which volatile context
    00121         should be copied into the context record.
    00122
    00123     ExceptionFrame - Supplies a pointer to an exception frame from which context
    00124         should be copied into the context record.
    00125
    00126     ContextFrame - Supplies a pointer to the context frame that receives the
    00127         context copied from the trap and exception frames.
    00128
    00129 Return Value:
    00130
    00131     None.
    00132
    00133 --*/
    00134
    00135 {
    00136
    00137     //
    00138     // Set control information if specified.
    00139     //
    00140
    00141     if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00142
    00143         //
    00144         // Set integer register gp, ra, sp, FIR, and PSR from trap frame.
    00145         //
    00146
    00147         ContextFrame->IntGp = TrapFrame->IntGp;
    00148         ContextFrame->IntSp = TrapFrame->IntSp;
    00149         ContextFrame->IntRa = TrapFrame->IntRa;
    00150         ContextFrame->Fir = TrapFrame->Fir;
    00151         ContextFrame->Psr = TrapFrame->Psr;
    00152     }
    00153
    00154     //
    00155     // Set integer register contents if specified.
    00156     //
    00157
    00158     if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00159
    00160         //
    00161         // Set volatile integer registers v0 and t0 - t7 from trap frame.
    00162         //
    00163
    00164         ContextFrame->IntV0 = TrapFrame->IntV0;
    00165         ContextFrame->IntT0 = TrapFrame->IntT0;
    00166         ContextFrame->IntT1 = TrapFrame->IntT1;
    00167         ContextFrame->IntT2 = TrapFrame->IntT2;
    00168         ContextFrame->IntT3 = TrapFrame->IntT3;
    00169         ContextFrame->IntT4 = TrapFrame->IntT4;
    00170         ContextFrame->IntT5 = TrapFrame->IntT5;
    00171         ContextFrame->IntT6 = TrapFrame->IntT6;
    00172         ContextFrame->IntT7 = TrapFrame->IntT7;
    00173
    00174         //
    00175         // Set nonvolatile integer registers s0 - s5 from exception frame.
    00176         //
    00177
    00178         ContextFrame->IntS0 = ExceptionFrame->IntS0;
    00179         ContextFrame->IntS1 = ExceptionFrame->IntS1;
    00180         ContextFrame->IntS2 = ExceptionFrame->IntS2;
    00181         ContextFrame->IntS3 = ExceptionFrame->IntS3;
    00182         ContextFrame->IntS4 = ExceptionFrame->IntS4;
    00183         ContextFrame->IntS5 = ExceptionFrame->IntS5;
    00184
    00185         //
    00186         // Set volatile integer registers a0 - a5, and t8 - t11 from trap
    00187         // frame.
    00188         //
    00189
    00190         ContextFrame->IntA0 = TrapFrame->IntA0;
    00191         ContextFrame->IntA1 = TrapFrame->IntA1;
    00192         ContextFrame->IntA2 = TrapFrame->IntA2;
    00193         ContextFrame->IntA3 = TrapFrame->IntA3;
    00194         ContextFrame->IntA4 = TrapFrame->IntA4;
    00195         ContextFrame->IntA5 = TrapFrame->IntA5;
    00196
    00197         ContextFrame->IntT8 = TrapFrame->IntT8;
    00198         ContextFrame->IntT9 = TrapFrame->IntT9;
    00199         ContextFrame->IntT10 = TrapFrame->IntT10;
    00200         ContextFrame->IntT11 = TrapFrame->IntT11;
    00201
    00202         //
    00203         // Set volatile integer registers fp, t12 and at from trap frame.
    00204         // Set integer register zero.
    00205         //
    00206
    00207         ContextFrame->IntFp = TrapFrame->IntFp;
    00208         ContextFrame->IntT12 = TrapFrame->IntT12;
    00209         ContextFrame->IntAt = TrapFrame->IntAt;
    00210         ContextFrame->IntZero = 0;
    00211     }
    00212
    00213     //
    00214     // Set floating register contents if specified.
    00215     //
    00216
    00217     if ((ContextFrame->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00218
    00219         //
    00220         // Set volatile floating registers f0 - f1 from trap frame.
    00221         // Set volatile floating registers f10 - f30 from trap frame.
    00222         // Set floating zero register f31 to 0.
    00223         //
    00224
    00225         ContextFrame->FltF0 = TrapFrame->FltF0;
    00226         ContextFrame->FltF1 = TrapFrame->FltF1;
    00227         RtlMoveMemory(&ContextFrame->FltF10, &TrapFrame->FltF10,
    00228                       sizeof(ULONGLONG) * 21);
    00229         ContextFrame->FltF31 = 0;
    00230
    00231         //
    00232         // Set nonvolatile floating registers f2 - f9 from exception frame.
    00233         //
    00234
    00235         ContextFrame->FltF2 = ExceptionFrame->FltF2;
    00236         ContextFrame->FltF3 = ExceptionFrame->FltF3;
    00237         ContextFrame->FltF4 = ExceptionFrame->FltF4;
    00238         ContextFrame->FltF5 = ExceptionFrame->FltF5;
    00239         ContextFrame->FltF6 = ExceptionFrame->FltF6;
    00240         ContextFrame->FltF7 = ExceptionFrame->FltF7;
    00241         ContextFrame->FltF8 = ExceptionFrame->FltF8;
    00242         ContextFrame->FltF9 = ExceptionFrame->FltF9;
    00243
    00244         //
    00245         // Set floating point control register from trap frame.
    00246         // Clear software floating point control register in context frame
    00247         // (if necessary, it can be set to the proper value by the caller).
    00248         //
    00249
    00250         ContextFrame->Fpcr = TrapFrame->Fpcr;
    00251         ContextFrame->SoftFpcr = 0;
    00252     }
    00253
    00254     return;
    00255 }

VOID KeContextToKframes | ( | IN OUT PKTRAP_FRAME | TrapFrame,
|  | IN OUT PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN PCONTEXT | ContextFrame,
|  | IN ULONG | ContextFlags,
|  | IN KPROCESSOR_MODE | PreviousMode
| ) |

Definition at line 258 of file alpha/exceptn.c.

References CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, CONTEXT_INTEGER, KeGetCurrentThread, KeGetPcr, and KernelMode.

Referenced by Ke386SetIOPL(), KiContinue(), KiContinuePreviousModeUser(), KiDispatchException(), KiInitializeContextThread(), KiRaiseException(), KiRestoreProcessorState(), and PspSetContext().

    00268                    :
    00269
    00270     This routine moves the selected contents of the specified context frame into
    00271     the specified trap and exception frames according to the specified context
    00272     flags.
    00273
    00274 Arguments:
    00275
    00276     TrapFrame - Supplies a pointer to a trap frame that receives the volatile
    00277         context from the context record.
    00278
    00279     ExceptionFrame - Supplies a pointer to an exception frame that receives
    00280         the nonvolatile context from the context record.
    00281
    00282     ContextFrame - Supplies a pointer to a context frame that contains the
    00283         context that is to be copied into the trap and exception frames.
    00284
    00285     ContextFlags - Supplies the set of flags that specify which parts of the
    00286         context frame are to be copied into the trap and exception frames.
    00287
    00288     PreviousMode - Supplies the processor mode for which the trap and exception
    00289         frames are being built.
    00290
    00291 Return Value:
    00292
    00293     None.
    00294
    00295 --*/
    00296
    00297 {
    00298
    00299     //
    00300     // Set control information if specified.
    00301     //
    00302
    00303     if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
    00304
    00305         //
    00306         // Set integer register gp, sp, ra, FIR, and PSR in trap frame.
    00307         //
    00308
    00309         TrapFrame->IntGp = ContextFrame->IntGp;
    00310         TrapFrame->IntSp = ContextFrame->IntSp;
    00311         TrapFrame->IntRa = ContextFrame->IntRa;
    00312         TrapFrame->Fir = ContextFrame->Fir;
    00313         TrapFrame->Psr = SANITIZE_PSR(ContextFrame->Psr, PreviousMode);
    00314     }
    00315
    00316     //
    00317     // Set integer register contents if specified.
    00318     //
    00319
    00320     if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
    00321
    00322         //
    00323         // Set volatile integer registers v0 and t0 - t7 in trap frame.
    00324         //
    00325
    00326         TrapFrame->IntV0 = ContextFrame->IntV0;
    00327         TrapFrame->IntT0 = ContextFrame->IntT0;
    00328         TrapFrame->IntT1 = ContextFrame->IntT1;
    00329         TrapFrame->IntT2 = ContextFrame->IntT2;
    00330         TrapFrame->IntT3 = ContextFrame->IntT3;
    00331         TrapFrame->IntT4 = ContextFrame->IntT4;
    00332         TrapFrame->IntT5 = ContextFrame->IntT5;
    00333         TrapFrame->IntT6 = ContextFrame->IntT6;
    00334         TrapFrame->IntT7 = ContextFrame->IntT7;
    00335
    00336         //
    00337         // Set nonvolatile integer registers s0 - s5 in exception frame.
    00338         //
    00339
    00340         ExceptionFrame->IntS0 = ContextFrame->IntS0;
    00341         ExceptionFrame->IntS1 = ContextFrame->IntS1;
    00342         ExceptionFrame->IntS2 = ContextFrame->IntS2;
    00343         ExceptionFrame->IntS3 = ContextFrame->IntS3;
    00344         ExceptionFrame->IntS4 = ContextFrame->IntS4;
    00345         ExceptionFrame->IntS5 = ContextFrame->IntS5;
    00346
    00347         //
    00348         // Set volatile integer registers a0 - a5, and t8 - t11 in trap frame.
    00349         //
    00350
    00351         TrapFrame->IntA0 = ContextFrame->IntA0;
    00352         TrapFrame->IntA1 = ContextFrame->IntA1;
    00353         TrapFrame->IntA2 = ContextFrame->IntA2;
    00354         TrapFrame->IntA3 = ContextFrame->IntA3;
    00355         TrapFrame->IntA4 = ContextFrame->IntA4;
    00356         TrapFrame->IntA5 = ContextFrame->IntA5;
    00357
    00358         TrapFrame->IntT8 = ContextFrame->IntT8;
    00359         TrapFrame->IntT9 = ContextFrame->IntT9;
    00360         TrapFrame->IntT10 = ContextFrame->IntT10;
    00361         TrapFrame->IntT11 = ContextFrame->IntT11;
    00362
    00363         //
    00364         // Set volatile integer registers fp, t12 and at in trap frame.
    00365         //
    00366
    00367         TrapFrame->IntFp = ContextFrame->IntFp;
    00368         TrapFrame->IntT12 = ContextFrame->IntT12;
    00369         TrapFrame->IntAt = ContextFrame->IntAt;
    00370     }
    00371
    00372     //
    00373     // Set floating register contents if specified.
    00374     //
    00375
    00376     if ((ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT) {
    00377
    00378         //
    00379         // Set volatile floating registers f0 - f1 in trap frame.
    00380         // Set volatile floating registers f10 - f30 in trap frame.
    00381         //
    00382
    00383         TrapFrame->FltF0 = ContextFrame->FltF0;
    00384         TrapFrame->FltF1 = ContextFrame->FltF1;
    00385         RtlMoveMemory(&TrapFrame->FltF10, &ContextFrame->FltF10,
    00386                       sizeof(ULONGLONG) * 21);
    00387
    00388         //
    00389         // Set nonvolatile floating registers f2 - f9 in exception frame.
    00390         //
    00391
    00392         ExceptionFrame->FltF2 = ContextFrame->FltF2;
    00393         ExceptionFrame->FltF3 = ContextFrame->FltF3;
    00394         ExceptionFrame->FltF4 = ContextFrame->FltF4;
    00395         ExceptionFrame->FltF5 = ContextFrame->FltF5;
    00396         ExceptionFrame->FltF6 = ContextFrame->FltF6;
    00397         ExceptionFrame->FltF7 = ContextFrame->FltF7;
    00398         ExceptionFrame->FltF8 = ContextFrame->FltF8;
    00399         ExceptionFrame->FltF9 = ContextFrame->FltF9;
    00400
    00401         //
    00402         // Set floating point control register in trap frame.
    00403         //
    00404
    00405         TrapFrame->Fpcr = ContextFrame->Fpcr;
    00406     }
    00407
    00408     return;
    00409 }

VOID KeCopyTrapDispatcher | ( | VOID |  | ) |

NTKERNELAPI NTSTATUS KeDelayExecutionThread | ( | IN KPROCESSOR_MODE | WaitMode,
|  | IN BOOLEAN | Alertable,
|  | IN PLARGE_INTEGER | Interval
| ) |

Definition at line 140 of file wait.c.

References _KTHREAD::Alertable, APC_LEVEL, _KTHREAD::ApcState, ASSERT, _KTHREAD::BasePriority, DelayExecution, DISPATCH_LEVEL, _KTIMER::DueTime, FALSE, _KTIMER::Header, KeGetCurrentPrcb, KeGetCurrentThread, _KAPC_STATE::KernelApcPending, KiActivateWaiterQueue(), KiComputeWaitInterval(), KiFindReadyThread(), KiInsertTreeTimer(), KiInsertWaitList, KiLockDispatcherDatabase, KiReadyThread(), KiSetPriorityThread(), KiSwapThread(), KiUnlockDispatcherDatabase(), _KTHREAD::NextProcessor, _KWAIT_BLOCK::NextWaitBlock, NTSTATUS(), NULL, _KTHREAD::Preempted, _KTHREAD::Priority, _KTHREAD::PriorityDecrement, _KAPC_STATE::Process, _KTHREAD::Quantum, _KTHREAD::Queue, _KTHREAD::State, TestForAlertPending, _KPROCESS::ThreadQuantum, _KTHREAD::Timer, TIMER_WAIT_BLOCK, TRUE, _KTHREAD::WaitBlock, _KTHREAD::WaitBlockList, Waiting, _KTHREAD::WaitIrql, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, _KTHREAD::WaitMode, _KTHREAD::WaitNext, _KTHREAD::WaitReason, _KTHREAD::WaitStatus, and _KTHREAD::WaitTime.

Referenced by CcPurgeCacheSection(), IoCancelThreadIo(), IopCancelAlertedRequest(), IopStartNetworkForRemoteBoot(), KiInitMachineDependent(), MemPrintFlush(), MemPrintWriteThread(), MiAllocateContiguousMemory(), MiCheckControlAreaStatus(), MiCheckSystemTrimEndCriteria(), MiCleanSection(), MiCloneProcessAddressSpace(), MiDispatchFault(), MiEmptyWorkingSet(), MiFlushAllPages(), MiFlushSectionInternal(), MiMakeOutswappedPageResident(), MiModifiedPageWriter(), MiModifiedPageWriterWorker(), MiPurgeImageSection(), MiRemoveUnusedSegments(), MiResolveProtoPteFault(), MiWriteComplete(), MmAccessFault(), MmCopyToCachedPage(), MmFlushSection(), MmFlushVirtualMemory(), MmGatherMemoryForHibernate(), MmGetSystemRoutineAddress(), MmRemovePhysicalMemory(), MmShutdownSystem(), MmWorkingSetManager(), NtCancelIoFile(), NtCreateSection(), NtDelayExecution(), Reader(), ReaderTurnedWriter(), UserBeep(), UserSleep(), Writer(), and xxxLW_LoadFonts().

    00148                    :
    00149
    00150     This function delays the execution of the current thread for the specified
    00151     interval of time.
    00152
    00153 Arguments:
    00154
    00155     WaitMode  - Supplies the processor mode in which the delay is to occur.
    00156
    00157     Alertable - Supplies a boolean value that specifies whether the delay
    00158         is alertable.
    00159
    00160     Interval - Supplies a pointer to the absolute or relative time over which
    00161         the delay is to occur.
    00162
    00163 Return Value:
    00164
    00165     The wait completion status. A value of STATUS_SUCCESS is returned if
    00166     the delay occurred. A value of STATUS_ALERTED is returned if the wait
    00167     was aborted to deliver an alert to the current thread. A value of
    00168     STATUS_USER_APC is returned if the wait was aborted to deliver a user
    00169     APC to the current thread.
    00170
    00171 --*/
    00172
    00173 {
    00174
    00175     LARGE_INTEGER DueTime;
    00176     LARGE_INTEGER NewTime;
    00177     PLARGE_INTEGER OriginalTime;
    00178     PKPRCB Prcb;
    00179     KPRIORITY Priority;
    00180     PRKQUEUE Queue;
    00181     PRKTHREAD Thread;
    00182     PRKTIMER Timer;
    00183     PKWAIT_BLOCK WaitBlock;
    00184     NTSTATUS WaitStatus;
    00185
    00186     //
    00187     // If the dispatcher database lock is not already held, then set the wait
    00188     // IRQL and lock the dispatcher database. Else set boolean wait variable
    00189     // to FALSE.
    00190     //
    00191
    00192     Thread = KeGetCurrentThread();
    00193     if (Thread->WaitNext) {
    00194         Thread->WaitNext = FALSE;
    00195
    00196     } else {
    00197         KiLockDispatcherDatabase(&Thread->WaitIrql);
    00198     }
    00199
    00200     //
    00201     // Start of delay loop.
    00202     //
    00203     // Note this loop is repeated if a kernel APC is delivered in the middle
    00204     // of the delay or a kernel APC is pending on the first attempt through
    00205     // the loop.
    00206     //
    00207
    00208     OriginalTime = Interval;
    00209     WaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
    00210     do {
    00211
    00212         //
    00213         // Test to determine if a kernel APC is pending.
    00214         //
    00215         // If a kernel APC is pending and the previous IRQL was less than
    00216         // APC_LEVEL, then a kernel APC was queued by another processor just
    00217         // after IRQL was raised to DISPATCH_LEVEL, but before the dispatcher
    00218         // database was locked.
    00219         //
    00220         // N.B. that this can only happen in a multiprocessor system.
    00221         //
    00222
    00223         if (Thread->ApcState.KernelApcPending && (Thread->WaitIrql < APC_LEVEL)) {
    00224
    00225             //
    00226             // Unlock the dispatcher database and lower IRQL to its previous
    00227             // value. An APC interrupt will immediately occur which will result
    00228             // in the delivery of the kernel APC if possible.
    00229             //
    00230
    00231             KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00232
    00233         } else {
    00234
    00235             //
    00236             // Test for alert pending.
    00237             //
    00238
    00239             TestForAlertPending(Alertable);
    00240
    00241             //
    00242             // Initialize wait block, insert wait block in timer wait list,
    00243             // insert timer in timer queue, put thread in wait state, select
    00244             // next thread to execute, and context switch to next thread.
    00245             //
    00246             // N.B. The timer wait block is initialized when the respective
    00247             //      thread is initialized. Thus the constant fields are not
    00248             //      reinitialized. These include the wait object, wait key,
    00249             //      wait type, and the wait list entry link pointers.
    00250             //
    00251
    00252             Thread->WaitBlockList = WaitBlock;
    00253             Thread->WaitStatus = (NTSTATUS)0;
    00254             Timer = &Thread->Timer;
    00255             WaitBlock->NextWaitBlock = WaitBlock;
    00256             Timer->Header.WaitListHead.Flink = &WaitBlock->WaitListEntry;
    00257             Timer->Header.WaitListHead.Blink = &WaitBlock->WaitListEntry;
    00258
    00259             //
    00260             // If the timer is inserted in the timer tree, then place the
    00261             // current thread in a wait state. Otherwise, attempt to force
    00262             // the current thread to yield the processor to another thread.
    00263             //
    00264
    00265             if (KiInsertTreeTimer(Timer, *Interval) == FALSE) {
    00266
    00267                 //
    00268                 // If the thread is not a realtime thread, then drop the
    00269                 // thread priority to the base priority.
    00270                 //
    00271
    00272                 Prcb = KeGetCurrentPrcb();
    00273                 Priority = Thread->Priority;
    00274                 if (Priority < LOW_REALTIME_PRIORITY) {
    00275                     if (Priority != Thread->BasePriority) {
    00276                         Thread->PriorityDecrement = 0;
    00277                         KiSetPriorityThread(Thread, Thread->BasePriority);
    00278                     }
    00279                 }
    00280
    00281                 //
    00282                 // If a new thread has not been selected, the attempt to round
    00283                 // robin the thread with other threads at the same priority.
    00284                 //
    00285
    00286                 if (Prcb->NextThread == NULL) {
    00287                     Prcb->NextThread = KiFindReadyThread(Thread->NextProcessor,
    00288                                                          Thread->Priority);
    00289                 }
    00290
    00291                 //
    00292                 // If a new thread has been selected for execution, then
    00293                 // switch immediately to the selected thread.
    00294                 //
    00295
    00296                 if (Prcb->NextThread != NULL) {
    00297
    00298                     //
    00299                     // Give the current thread a new qunatum and switch
    00300                     // context to selected thread.
    00301                     //
    00302                     // N.B. Control is returned at the original IRQL.
    00303                     //
    00304
    00305                     Thread->Preempted = FALSE;
    00306                     Thread->Quantum = Thread->ApcState.Process->ThreadQuantum;
    00307
    00308                     ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
    00309
    00310                     KiReadyThread(Thread);
    00311                     WaitStatus = (NTSTATUS)KiSwapThread();
    00312                     goto WaitComplete;
    00313
    00314                 } else {
    00315                     WaitStatus = (NTSTATUS)STATUS_SUCCESS;
    00316                     break;
    00317                 }
    00318             }
    00319
    00320             DueTime.QuadPart = Timer->DueTime.QuadPart;
    00321
    00322             //
    00323             // If the current thread is processing a queue entry, then attempt
    00324             // to activate another thread that is blocked on the queue object.
    00325             //
    00326
    00327             Queue = Thread->Queue;
    00328             if (Queue != NULL) {
    00329                 KiActivateWaiterQueue(Queue);
    00330             }
    00331
    00332             //
    00333             // Set the thread wait parameters, set the thread dispatcher state
    00334             // to Waiting, and insert the thread in the wait list.
    00335             //
    00336
    00337             Thread->Alertable = Alertable;
    00338             Thread->WaitMode = WaitMode;
    00339             Thread->WaitReason = DelayExecution;
    00340             Thread->WaitTime= KiQueryLowTickCount();
    00341             Thread->State = Waiting;
    00342             KiInsertWaitList(WaitMode, Thread);
    00343
    00344             //
    00345             // Switch context to selected thread.
    00346             //
    00347             // N.B. Control is returned at the original IRQL.
    00348             //
    00349
    00350             ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
    00351
    00352             WaitStatus = (NTSTATUS)KiSwapThread();
    00353
    00354             //
    00355             // If the thread was not awakened to deliver a kernel mode APC,
    00356             // then return the wait status.
    00357             //
    00358
    00359         WaitComplete:
    00360             if (WaitStatus != STATUS_KERNEL_APC) {
    00361                 if (WaitStatus == STATUS_TIMEOUT) {
    00362                     WaitStatus = STATUS_SUCCESS;
    00363                 }
    00364
    00365                 return WaitStatus;
    00366             }
    00367
    00368             //
    00369             // Reduce the time remaining before the time delay expires.
    00370             //
    00371
    00372             Interval = KiComputeWaitInterval(OriginalTime,
    00373                                              &DueTime,
    00374                                              &NewTime);
    00375         }
    00376
    00377         //
    00378         // Raise IRQL to DISPATCH_LEVEL and lock the dispatcher database.
    00379         //
    00380
    00381         KiLockDispatcherDatabase(&Thread->WaitIrql);
    00382     } while (TRUE);
    00383
    00384     //
    00385     // The thread is alerted or a user APC should be delivered. Unlock the
    00386     // dispatcher database, lower IRQL to its previous value, and return the
    00387     // wait status.
    00388     //
    00389
    00390     KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00391     return WaitStatus;
    00392 }

NTKERNELAPI BOOLEAN KeDeregisterBugCheckCallback | ( | IN PKBUGCHECK_CALLBACK_RECORD | CallbackRecord | ) |

Definition at line 1064 of file bugcheck.c.

References BufferEmpty, BufferInserted, FALSE, HIGH_LEVEL, KeBugCheckCallbackLock, KeLowerIrql(), KeRaiseIrql(), PKBUGCHECK_CALLBACK_RECORD, and TRUE.

    01070                    :
    01071
    01072     This function deregisters a bug check callback record.
    01073
    01074 Arguments:
    01075
    01076     CallbackRecord - Supplies a pointer to a bug check callback record.
    01077
    01078 Return Value:
    01079
    01080     If the specified bug check callback record is successfully deregistered,
    01081     then a value of TRUE is returned. Otherwise, a value of FALSE is returned.
    01082
    01083 --*/
    01084
    01085 {
    01086
    01087     BOOLEAN Deregister;
    01088     KIRQL OldIrql;
    01089
    01090     //
    01091     // Raise IRQL to HIGH_LEVEL and acquire the bug check callback list
    01092     // spinlock.
    01093     //
    01094
    01095     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    01096     KiAcquireSpinLock(&KeBugCheckCallbackLock);
    01097
    01098     //
    01099     // If the specified callback record is currently registered, then
    01100     // deregister the callback record.
    01101     //
    01102
    01103     Deregister = FALSE;
    01104     if (CallbackRecord->State == BufferInserted) {
    01105         CallbackRecord->State = BufferEmpty;
    01106         RemoveEntryList(&CallbackRecord->Entry);
    01107         Deregister = TRUE;
    01108     }
    01109
    01110     //
    01111     // Release the bug check callback spinlock, lower IRQL to its previous
    01112     // value, and return whether the callback record was successfully
    01113     // deregistered.
    01114     //
    01115
    01116     KiReleaseSpinLock(&KeBugCheckCallbackLock);
    01117     KeLowerIrql(OldIrql);
    01118     return Deregister;
    01119 }

NTKERNELAPI VOID KeDetachProcess | ( | VOID |  | ) |

Definition at line 405 of file procobj.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, _KTHREAD::ApcStatePointer, ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, FALSE, _KEVENT::Header, KeBugCheck(), KeGetCurrentThread, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiMoveApcState(), KiProcessOutSwapListHead, KiRequestSoftwareInterrupt(), KiSwapEvent, KiSwapProcess(), KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KAPC_STATE::Process, ProcessInTransition, _KTHREAD::SavedApcState, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, _KPROCESS::ThreadListHead, TRUE, UserMode, and _DISPATCHER_HEADER::WaitListHead.

Referenced by _GetComboBoxInfo(), _GetListBoxInfo(), CheckWHFBits(), MiCloneProcessAddressSpace(), MiCreatePebOrTeb(), MiDoMappedCopy(), MiDoPoolCopy(), MiEmptyAllWorkingSetsWorker(), MiGetWorkingSetInfo(), MiLoadImageSection(), MiLoadSystemImage(), MmAssignProcessToJob(), MmCreatePeb(), MmCreateTeb(), MmDeleteTeb(), MmFlushVirtualMemory(), MmInitializeProcessAddressSpace(), MmMapViewOfSection(), MmProbeAndLockProcessPages(), MmSetBankedSection(), MmSetMemoryPriorityProcess(), MmUnmapViewOfSection(), MmWorkingSetManager(), NtAllocateUserPhysicalPages(), NtAllocateVirtualMemory(), NtDuplicateObject(), NtFlushInstructionCache(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtLockVirtualMemory(), NtProtectVirtualMemory(), NtQueryVirtualMemory(), NtSetInformationJobObject(), NtSetInformationProcess(), NtUnlockVirtualMemory(), ObReferenceObjectByHandle(), PsAssignImpersonationToken(), PspAddProcessToJob(), PspCreateProcess(), PspSetQuotaLimits(), SepRmCallLsa(), SetProcessFlags(), SmbTraceCompleteRdr(), SmbTraceDisconnect(), SmbTraceStop(), xxxCheckImeShowStatus(), xxxCreateDisconnectDesktop(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxImmActivateAndUnloadThreadsLayout(), xxxMinMaximize(), xxxNotifyImeShowStatus(), xxxSendMessageToUI(), and zzzSetWindowsHookEx().

    00411                    :
    00412
    00413     This function detaches a thread from another process' address space.
    00414
    00415 Arguments:
    00416
    00417     None.
    00418
    00419 Return Value:
    00420
    00421     None.
    00422
    00423 --*/
    00424
    00425 {
    00426
    00427     KIRQL OldIrql;
    00428     PKPROCESS Process;
    00429     PKTHREAD Thread;
    00430
    00431     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00432
    00433     //
    00434     // Raise IRQL to dispatcher level and lock dispatcher database.
    00435     //
    00436
    00437     Thread = KeGetCurrentThread();
    00438     KiLockDispatcherDatabase(&OldIrql);
    00439
    00440     //
    00441     // If the current thread is attached to another process, then detach
    00442     // it.
    00443     //
    00444
    00445     if (Thread->ApcStateIndex != 0) {
    00446
    00447         //
    00448         // Check if a kernel APC is in progress, the kernel APC queue is
    00449         // not empty, or the user APC queue is not empty. If any of these
    00450         // conditions are true, then call bug check.
    00451         //
    00452
    00453 #if DBG
    00454
    00455         if ((Thread->ApcState.KernelApcInProgress) ||
    00456             (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) ||
    00457             (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) {
    00458             KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
    00459         }
    00460
    00461 #endif
    00462
    00463         //
    00464         // Unbias current process stack count and check if the process should
    00465         // be swapped out of memory.
    00466         //
    00467
    00468         Process = Thread->ApcState.Process;
    00469         Process->StackCount -= 1;
    00470         if ((Process->StackCount == 0) &&
    00471             (IsListEmpty(&Process->ThreadListHead) == FALSE)) {
    00472             Process->State = ProcessInTransition;
    00473             InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry);
    00474             KiSwapEvent.Header.SignalState = 1;
    00475             if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
    00476                 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
    00477             }
    00478         }
    00479
    00480         //
    00481         // Restore APC state and check whether the kernel APC queue contains
    00482         // an entry. If the kernel APC queue contains an entry then set kernel
    00483         // APC pending and request a software interrupt at APC_LEVEL.
    00484         //
    00485
    00486         KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
    00487         Thread->SavedApcState.Process = (PKPROCESS)NULL;
    00488         Thread->ApcStatePointer[0] = &Thread->ApcState;
    00489         Thread->ApcStatePointer[1] = &Thread->SavedApcState;
    00490         Thread->ApcStateIndex = 0;
    00491         if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) {
    00492             Thread->ApcState.KernelApcPending = TRUE;
    00493             KiRequestSoftwareInterrupt(APC_LEVEL);
    00494         }
    00495
    00496         //
    00497         // Swap the address space back to the parent process.
    00498         //
    00499
    00500         KiSwapProcess(Thread->ApcState.Process, Process);
    00501     }
    00502
    00503     //
    00504     // Lower IRQL to its previous value and return.
    00505     //
    00506
    00507     KiUnlockDispatcherDatabase(OldIrql);
    00508     return;
    00509 }

BOOLEAN KeDisableApcQueuingThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 574 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by PspExitThread().

    00580                    :
    00581
    00582     This function disables the queuing of APC's to the specified thread.
    00583
    00584 Arguments:
    00585
    00586     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00587
    00588 Return Value:
    00589
    00590     The previous value of the APC queuing state variable.
    00591
    00592 --*/
    00593
    00594 {
    00595
    00596     BOOLEAN ApcQueueable;
    00597     KIRQL OldIrql;
    00598
    00599     ASSERT_THREAD(Thread);
    00600     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00601
    00602     //
    00603     // Raise IRQL to dispatcher level and lock dispatcher database.
    00604     //
    00605
    00606     KiLockDispatcherDatabase(&OldIrql);
    00607
    00608     //
    00609     // Capture the current state of the APC queueable state variable and
    00610     // set its state to FALSE.
    00611     //
    00612
    00613     ApcQueueable = Thread->ApcQueueable;
    00614     Thread->ApcQueueable = FALSE;
    00615
    00616     //
    00617     // Unlock dispatcher database and lower IRQL to its previous
    00618     // value.
    00619     //
    00620
    00621     KiUnlockDispatcherDatabase(OldIrql);
    00622
    00623     //
    00624     // Return the previous APC queueable state.
    00625     //
    00626
    00627     return ApcQueueable;
    00628 }

NTKERNELAPI BOOLEAN KeDisconnectInterrupt | ( | IN PKINTERRUPT | Interrupt | ) |

Definition at line 298 of file alpha/intobj.c.

References _KINTERRUPT::DispatchAddress, _KINTERRUPT::DispatchCode, FALSE, HalDisableSystemInterrupt(), _KINTERRUPT::InterruptListEntry, KeLowerIrql(), KeRaiseIrql(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KeSweepIcache(), KiChainedDispatch(), KiFloatingDispatch(), KiInterruptDispatchRaise(), KiInterruptDispatchSame(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), max, SYNCH_LEVEL, and TRUE.

Referenced by IoDisconnectInterrupt(), and KeConnectInterrupt().

    00304                    :
    00305
    00306     This function disconnects an interrupt object from the interrupt vector
    00307     specified by the interrupt object. If the interrupt object is not
    00308     connected, then a value of FALSE is returned. Else the specified interrupt
    00309     object is disconnected from the interrupt vector, the connected state is
    00310     set to FALSE, and TRUE is returned as the function value.
    00311
    00312 Arguments:
    00313
    00314     Interrupt - Supplies a pointer to a control object of type interrupt.
    00315
    00316 Return Value:
    00317
    00318     If the interrupt object is not connected, then a value of FALSE is
    00319     returned. Else a value of TRUE is returned.
    00320
    00321 --*/
    00322
    00323 {
    00324
    00325     BOOLEAN Connected;
    00326     PKINTERRUPT Interruptx;
    00327     PKINTERRUPT Interrupty;
    00328     KIRQL Irql;
    00329     KIRQL OldIrql;
    00330     ULONG Vector;
    00331
    00332     //
    00333     // Set system affinity to the specified processor.
    00334     //
    00335
    00336     KeSetSystemAffinityThread((KAFFINITY)(1 << Interrupt->Number));
    00337
    00338     //
    00339     // Raise IRQL to dispatcher level and lock dispatcher database.
    00340     //
    00341
    00342     KiLockDispatcherDatabase(&OldIrql);
    00343
    00344     //
    00345     // If the interrupt object is connected, then disconnect it from the
    00346     // specified vector.
    00347     //
    00348
    00349     Connected = Interrupt->Connected;
    00350     if (Connected != FALSE) {
    00351         Irql = Interrupt->Irql;
    00352         Vector = Interrupt->Vector;
    00353
    00354         //
    00355         // If the specified interrupt vector is not connected to the chained
    00356         // interrupt dispatcher, then disconnect it by setting its dispatch
    00357         // address to the unexpected interrupt routine. Else remove the
    00358         // interrupt object from the interrupt chain. If there is only
    00359         // one entry remaining in the list, then reestablish the dispatch
    00360         // address.
    00361         //
    00362
    00363         Interruptx = CONTAINING_RECORD(PCR->InterruptRoutine[Vector],
    00364                                        KINTERRUPT,
    00365                                        DispatchCode[0]);
    00366
    00367         if (Interruptx->DispatchAddress == KiChainedDispatch) {
    00368             ASSERT (Irql <= KiSynchIrql);
    00369             if (Interrupt == Interruptx) {
    00370                 Interruptx = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink,
    00371                                                KINTERRUPT, InterruptListEntry);
    00372                 Interruptx->DispatchAddress = KiChainedDispatch;
    00373                 PCR->InterruptRoutine[Vector] =
    00374                                 (PKINTERRUPT_ROUTINE)(&Interruptx->DispatchCode);
    00375
    00376             }
    00377
    00378             RemoveEntryList(&Interrupt->InterruptListEntry);
    00379             Interrupty = CONTAINING_RECORD(Interruptx->InterruptListEntry.Flink,
    00380                                            KINTERRUPT,
    00381                                            InterruptListEntry);
    00382
    00383             if (Interruptx == Interrupty) {
    00384                 if (Interrupty->FloatingSave) {
    00385                     Interrupty->DispatchAddress = KiFloatingDispatch;
    00386
    00387                 } else {
    00388                     if (Interrupty->Irql == Interrupty->SynchronizeIrql) {
    00389                         Interrupty->DispatchAddress =
    00390                                     (PKINTERRUPT_ROUTINE)KiInterruptDispatchSame;
    00391
    00392                     } else {
    00393                         Interrupty->DispatchAddress =
    00394                                     (PKINTERRUPT_ROUTINE)KiInterruptDispatchRaise;
    00395                     }
    00396                 }
    00397
    00398                 PCR->InterruptRoutine[Vector] =
    00399                                (PKINTERRUPT_ROUTINE)(&Interrupty->DispatchCode);
    00400
    00401                 }
    00402
    00403         } else {
    00404             HalDisableSystemInterrupt(Vector, Irql);
    00405             PCR->InterruptRoutine[Vector] =
    00406                 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode);
    00407         }
    00408
    00409         KeSweepIcache(TRUE);
    00410         Interrupt->Connected = FALSE;
    00411     }
    00412
    00413     //
    00414     // Unlock dispatcher database and lower IRQL to its previous value.
    00415     //
    00416
    00417     KiUnlockDispatcherDatabase(OldIrql);
    00418
    00419     //
    00420     // Set system affinity back to the original value.
    00421     //
    00422
    00423     KeRevertToUserAffinityThread();
    00424
    00425     //
    00426     // Return whether interrupt was disconnected from the specified vector.
    00427     //
    00428
    00429     return Connected;
    00430 }

VOID KeDumpMachineState | ( | IN PKPROCESSOR_STATE | ProcessorState,
|  | IN PCHAR | Buffer,
|  | IN PULONG_PTR | BugCheckParameters,
|  | IN ULONG | NumberOfParameters,
|  | IN PKE_BUGCHECK_UNICODE_TO_ANSI | UnicodeToAnsiRoutine
| ) |

BOOLEAN KeEnableApcQueuingThread | ( | IN | PKTHREAD | ) |

Definition at line 631 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and TRUE.

Referenced by PspCreateThread().

    00637                    :
    00638
    00639     This function enables the queuing of APC's to the specified thread.
    00640
    00641 Arguments:
    00642
    00643     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00644
    00645 Return Value:
    00646
    00647     The previous value of the APC queuing state variable.
    00648
    00649 --*/
    00650
    00651 {
    00652
    00653     BOOLEAN ApcQueueable;
    00654     KIRQL OldIrql;
    00655
    00656     ASSERT_THREAD(Thread);
    00657     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00658
    00659     //
    00660     // Raise IRQL to dispatcher level and lock dispatcher database.
    00661     //
    00662
    00663     KiLockDispatcherDatabase(&OldIrql);
    00664
    00665     //
    00666     // Capture the current state of the APC queueable state variable and
    00667     // set its state to TRUE.
    00668     //
    00669
    00670     ApcQueueable = Thread->ApcQueueable;
    00671     Thread->ApcQueueable = TRUE;
    00672
    00673     //
    00674     // Unlock dispatcher database and lower IRQL to its previous
    00675     // value.
    00676     //
    00677
    00678     KiUnlockDispatcherDatabase(OldIrql);
    00679
    00680     //
    00681     // Return previous APC queueable state.
    00682     //
    00683
    00684     return ApcQueueable;
    00685 }

NTKERNELAPI VOID KeEnterKernelDebugger | ( | VOID |  | ) |

Definition at line 1015 of file bugcheck.c.

References FALSE, HIGH_LEVEL, KdDebuggerEnabled, KdInitSystem(), KdPitchDebugger, KeBugCheckCount, KeRaiseIrql(), KiBugCheckDebugBreak(), KiDisableInterrupts(), KiHardwareTrigger, and NULL.

    01021                    :
    01022
    01023     This function crashes the system in a controlled manner attempting
    01024     to invoke the kernel debugger.
    01025
    01026 Arguments:
    01027
    01028     None.
    01029
    01030 Return Value:
    01031
    01032     None.
    01033
    01034 --*/
    01035
    01036 {
    01037
    01038 #if !defined(i386)
    01039     KIRQL OldIrql;
    01040 #endif
    01041
    01042     //
    01043     // Freeze execution of the system by disabling interrupts and looping.
    01044     //
    01045
    01046     KiHardwareTrigger = 1;
    01047     KiDisableInterrupts();
    01048 #if !defined(i386)
    01049     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    01050 #endif
    01051     if (InterlockedDecrement (&KeBugCheckCount) == 0) {
    01052         if (KdDebuggerEnabled == FALSE) {
    01053             if ( KdPitchDebugger == FALSE ) {
    01054                 KdInitSystem(NULL, FALSE);
    01055             }
    01056         }
    01057     }
    01058
    01059     KiBugCheckDebugBreak (DBG_STATUS_FATAL);
    01060 }

NTKERNELAPI PCONFIGURATION_COMPONENT_DATA KeFindConfigurationEntry | ( | IN PCONFIGURATION_COMPONENT_DATA | Child,
|  | IN CONFIGURATION_CLASS | Class,
|  | IN CONFIGURATION_TYPE | Type,
|  | IN PULONG Key | OPTIONAL
| ) |

Definition at line 34 of file config.c.

References KeFindConfigurationNextEntry(), Key, and NULL.

Referenced by CmpInitializeHardwareConfiguration().

    00042                    :
    00043
    00044     This function search the specified configuration tree and returns a
    00045     pointer to an entry that matches the specified class, type, and key
    00046     parameters.
    00047
    00048     This routine is the same as KeFindConfurationEntryNext expect
    00049     that the search is performed from the first entry
    00050
    00051     N.B. This routine can only be called during system initialization.
    00052
    00053 --*/
    00054 {
    00055     PCONFIGURATION_COMPONENT_DATA Resume;
    00056
    00057     Resume = NULL;
    00058     return KeFindConfigurationNextEntry (Child, Class, Type, Key, &Resume);
    00059 }

NTKERNELAPI PCONFIGURATION_COMPONENT_DATA KeFindConfigurationNextEntry | ( | IN PCONFIGURATION_COMPONENT_DATA | Child,
|  | IN CONFIGURATION_CLASS | Class,
|  | IN CONFIGURATION_TYPE | Type,
|  | IN PULONG Key | OPTIONAL,
|  | IN PCONFIGURATION_COMPONENT_DATA * | Resume
| ) |

Definition at line 62 of file config.c.

References _CONFIGURATION_COMPONENT_DATA::Child, _CONFIGURATION_COMPONENT::Class, _CONFIGURATION_COMPONENT_DATA::ComponentEntry, Key, _CONFIGURATION_COMPONENT::Key, NULL, _CONFIGURATION_COMPONENT_DATA::Sibling, and _CONFIGURATION_COMPONENT::Type.

Referenced by KeFindConfigurationEntry().

    00072                    :
    00073
    00074     This function search the specified configuration tree and returns a
    00075     pointer to an entry that matches the specified class, type, and key
    00076     parameters.
    00077
    00078     N.B. This routine can only be called during system initialization.
    00079
    00080 Arguments:
    00081
    00082     Child - Supplies an optional pointer to an NT configuration component.
    00083
    00084     Class - Supplies the configuration class of the entry to locate.
    00085
    00086     Type - Supplies the configuration type of the entry to locate.
    00087
    00088     Key - Supplies a pointer to an optional key value to use in locating
    00089         the specified entry.
    00090
    00091     Resume - Supplies the last returned entry for which the search
    00092         should resume from.
    00093
    00094 Return Value:
    00095
    00096     If the specified entry is located, then a pointer to the configuration
    00097     entry is returned as the function value. Otherwise, NULL is returned.
    00098
    00099 --*/
    00100
    00101 {
    00102
    00103     PCONFIGURATION_COMPONENT_DATA Entry;
    00104     ULONG MatchKey;
    00105     ULONG MatchMask;
    00106     PCONFIGURATION_COMPONENT_DATA Sibling;
    00107
    00108     //
    00109     // Initialize the match key and mask based on whether the optional key
    00110     // value is specified.
    00111     //
    00112
    00113     if (ARGUMENT_PRESENT(Key)) {
    00114         MatchMask = 0xffffffff;
    00115         MatchKey = *Key;
    00116
    00117     } else {
    00118         MatchMask = 0;
    00119         MatchKey = 0;
    00120     }
    00121
    00122     //
    00123     // Search specified configuration tree for an entry that matches the
    00124     // the specified class, type, and key.
    00125     //
    00126
    00127     while (Child != NULL) {
    00128         if (*Resume) {
    00129             //
    00130             // If resume location found, clear resume location and continue
    00131             // search with next entry
    00132             //
    00133
    00134             if (Child == *Resume) {
    00135                 *Resume = NULL;
    00136             }
    00137         } else {
    00138
    00139             //
    00140             // If the class, type, and key match, then return a pointer to
    00141             // the child entry.
    00142             //
    00143
    00144             if ((Child->ComponentEntry.Class == Class) &&
    00145                 (Child->ComponentEntry.Type == Type) &&
    00146                 ((Child->ComponentEntry.Key & MatchMask) == MatchKey)) {
    00147                 return Child;
    00148             }
    00149         }
    00150
    00151         //
    00152         // If the child has a sibling list, then search the sibling list
    00153         // for an entry that matches the specified class, type, and key.
    00154         //
    00155
    00156         Sibling = Child->Sibling;
    00157         while (Sibling != NULL) {
    00158             if (*Resume) {
    00159                 //
    00160                 // If resume location found, clear resume location and continue
    00161                 // search with next entry
    00162                 //
    00163
    00164                 if (Sibling == *Resume) {
    00165                     *Resume = NULL;
    00166                 }
    00167             } else {
    00168
    00169                 //
    00170                 // If the class, type, and key match, then return a pointer to
    00171                 // the child entry.
    00172                 //
    00173
    00174                 if ((Sibling->ComponentEntry.Class == Class) &&
    00175                     (Sibling->ComponentEntry.Type == Type) &&
    00176                     ((Sibling->ComponentEntry.Key & MatchMask) == MatchKey)) {
    00177                     return Sibling;
    00178                 }
    00179             }
    00180
    00181             //
    00182             // If the sibling has a child tree, then search the child tree
    00183             // for an entry that matches the specified class, type, and key.
    00184             //
    00185
    00186             if (Sibling->Child != NULL) {
    00187                Entry = KeFindConfigurationNextEntry (
    00188                                 Sibling->Child,
    00189                                 Class,
    00190                                 Type,
    00191                                 Key,
    00192                                 Resume
    00193                                 );
    00194
    00195                if (Entry != NULL) {
    00196                    return Entry;
    00197                }
    00198             }
    00199
    00200             Sibling = Sibling->Sibling;
    00201         }
    00202
    00203         Child = Child->Child;
    00204     }
    00205
    00206     return NULL;
    00207 }
    }

NTKERNELAPI VOID KeFlushCurrentTb | ( | VOID |  | ) |

| Referenced by KdpTrap(), KeFlushEntireTb(), KeThawExecution(), KiFlushEntireTbTarget(), KiFlushTargetEntireTb(), KiFreezeTargetExecution(), KiGetNewRid(), KiInitializeKernel(), KiSyncNewRegionId(), KiSyncNewRegionIdTarget(), KiSyncSessionTarget(), MiInitMachineDependent(), and MmMakeKernelResourceSectionWritable().

NTKERNELAPI VOID KeFlushEntireTb | ( | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcessors
| ) |

Definition at line 86 of file alpha/flushtb.c.

References ASSERT, IPI_INSTRUMENT_COUNT, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), and SYNCH_LEVEL.

Referenced by MiCheckVirtualAddress(), MiDownShareCountFlushEntireTb(), MiFlushPteList(), MiFlushUserPhysicalPteList(), MiHandleBankedSection(), MiInitMachineDependent(), MiMapBBTMemory(), MiMapLockedPagesInUserSpace(), MiMapPageInHyperSpace(), MiMapSinglePage(), MiMapViewOfPhysicalSection(), MiReleaseSystemPtes(), MiRemoveMappedView(), MiReserveSystemPtes(), MiResolveMappedFileFault(), MmAllocateNonCachedMemory(), MmFreeLoaderBlock(), MmMapIoSpace(), MmMapLockedPagesSpecifyCache(), MmMapUserAddressesToPage(), MmMapViewInSystemCache(), MmOutPageKernelStack(), MmSetAddressRangeModified(), and MmSetBankedSection().

    00093                    :
    00094
    00095     This function flushes the entire translation buffer (TB) on all
    00096     processors that are currently running threads which are children
    00097     of the current process or flushes the entire translation buffer
    00098     on all processors in the host configuration.
    00099
    00100 Arguments:
    00101
    00102     Invalid - Supplies a boolean value that specifies the reason for
    00103         flushing the translation buffer.
    00104
    00105     AllProcessors - Supplies a boolean value that determines which
    00106         translation buffers are to be flushed.
    00107
    00108 Return Value:
    00109
    00110     None.
    00111
    00112 --*/
    00113
    00114 {
    00115
    00116     KIRQL OldIrql;
    00117     PKPROCESS Process;
    00118     PKTHREAD Thread;
    00119     KAFFINITY TargetProcessors;
    00120
    00121     //
    00122     // Compute the target set of processors, disable context switching,
    00123     // and send the flush entire parameters to the target processors,
    00124     // if any, for execution.
    00125     //
    00126
    00127 #if defined(NT_UP)
    00128
    00129     __tbia();
    00130
    00131 #else
    00132
    00133     if (AllProcessors != FALSE) {
    00134         OldIrql = KeRaiseIrqlToSynchLevel();
    00135         TargetProcessors = KeActiveProcessors;
    00136
    00137     } else {
    00138         KiLockContextSwap(&OldIrql);
    00139         Thread = KeGetCurrentThread();
    00140         Process = Thread->ApcState.Process;
    00141         TargetProcessors = Process->ActiveProcessors;
    00142         if (TargetProcessors != Process->RunOnProcessors) {
    00143             Process->ProcessSequence = KiMasterSequence - 1;
    00144         }
    00145     }
    00146
    00147     TargetProcessors &= PCR->NotMember;
    00148     if (TargetProcessors != 0) {
    00149         KiIpiSendPacket(TargetProcessors,
    00150                         KiFlushEntireTbTarget,
    00151                         NULL,
    00152                         NULL,
    00153                         NULL);
    00154     }
    00155
    00156     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb);
    00157
    00158     //
    00159     // Flush TB on current processor.
    00160     //
    00161
    00162     // KeFlushCurrentTb();
    00163     __tbia();
    00164
    00165     //
    00166     // Wait until all target processors have finished.
    00167     //
    00168
    00169     if (TargetProcessors != 0) {
    00170         KiIpiStallOnPacketTargets(TargetProcessors);
    00171     }
    00172
    00173     if (AllProcessors != FALSE) {
    00174         KeLowerIrql(OldIrql);
    00175     } else {
    00176         KiUnlockContextSwap(OldIrql);
    00177     }
    00178
    00179 #endif
    00180
    00181     return;
    00182 }

VOID KeFlushMultipleTb | ( | IN ULONG | Number,
|  | IN PVOID * | Virtual,
|  | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcesors,
|  | IN PHARDWARE_PTE *PtePointer | OPTIONAL,
|  | IN HARDWARE_PTE | PteValue
| ) |

Definition at line 231 of file alpha/flushtb.c.

References ASSERT, DISPATCH_LEVEL, Index, IPI_INSTRUMENT_COUNT, KeGetCurrentPrcb, KiFlushSingleTb(), and Virtual.

Referenced by MiFlushPteList(), MiFlushUserPhysicalPteList(), MmOutPageKernelStack(), and MmSetAddressRangeModified().

    00242                    :
    00243
    00244     This function flushes multiple entries from the translation buffer
    00245     on all processors that are currently running threads which are
    00246     children of the current process or flushes a multiple entries from
    00247     the translation buffer on all processors in the host configuration.
    00248
    00249 Arguments:
    00250
    00251     Number - Supplies the number of TB entries to flush.
    00252
    00253     Virtual - Supplies a pointer to an array of virtual addresses that
    00254         are within the pages whose translation buffer entries are to be
    00255         flushed.
    00256
    00257     Invalid - Supplies a boolean value that specifies the reason for
    00258         flushing the translation buffer.
    00259
    00260     AllProcessors - Supplies a boolean value that determines which
    00261         translation buffers are to be flushed.
    00262
    00263     PtePointer - Supplies an optional pointer to an array of pointers to
    00264        page table entries that receive the specified page table entry
    00265        value.
    00266
    00267     PteValue - Supplies the the new page table entry value.
    00268
    00269 Return Value:
    00270
    00271     The previous contents of the specified page table entry is returned
    00272     as the function value.
    00273
    00274 --*/
    00275
    00276 {
    00277
    00278     ULONG Index;
    00279     KIRQL OldIrql;
    00280     PKPROCESS Process;
    00281     KAFFINITY TargetProcessors;
    00282     PKTHREAD Thread;
    00283
    00284     //
    00285     // Compute the target set of processors and send the flush multiple
    00286     // parameters to the target processors, if any, for execution.
    00287     //
    00288
    00289     if (AllProcessors != FALSE) {
    00290         OldIrql = KeRaiseIrqlToSynchLevel();
    00291         TargetProcessors = KeActiveProcessors;
    00292
    00293     } else {
    00294         KiLockContextSwap(&OldIrql);
    00295         Thread = KeGetCurrentThread();
    00296         Process = Thread->ApcState.Process;
    00297         TargetProcessors = Process->ActiveProcessors;
    00298         if (TargetProcessors != Process->RunOnProcessors) {
    00299             Process->ProcessSequence = KiMasterSequence - 1;
    00300         }
    00301     }
    00302
    00303     //
    00304     // If a page table entry address address is specified, then set the
    00305     // specified page table entries to the specific value.
    00306     //
    00307
    00308     if (ARGUMENT_PRESENT(PtePointer)) {
    00309         for (Index = 0; Index < Number; Index += 1) {
    00310             *PtePointer[Index] = PteValue;
    00311         }
    00312     }
    00313
    00314     TargetProcessors &= PCR->NotMember;
    00315     if (TargetProcessors != 0) {
    00316         KiIpiSendPacket(TargetProcessors,
    00317                         KiFlushMultipleTbTarget,
    00318                         ULongToPtr(Number),
    00319                         (PVOID)Virtual,
    00320                         NULL);
    00321     }
    00322
    00323     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushMultipleTb);
    00324
    00325     //
    00326     // Flush the specified entries from the TB on the current processor.
    00327     //
    00328
    00329     KiFlushMultipleTb(Invalid, &Virtual[0], Number);
    00330
    00331     //
    00332     // Wait until all target processors have finished.
    00333     //
    00334
    00335     if (TargetProcessors != 0) {
    00336         KiIpiStallOnPacketTargets(TargetProcessors);
    00337     }
    00338
    00339     //
    00340     // If the context swap lock was acquired, release it.
    00341     //
    00342     if (AllProcessors != FALSE) {
    00343         KeLowerIrql(OldIrql);
    00344
    00345     } else {
    00346         KiUnlockContextSwap(OldIrql);
    00347     }
    00348
    00349     return;
    00350 }

PLIST_ENTRY KeFlushQueueApc | ( | IN PKTHREAD | Thread,
|  | IN KPROCESSOR_MODE | ProcessorMode
| ) |

Definition at line 138 of file apcobj.c.

References ASSERT, DISPATCH_LEVEL, FALSE, _KAPC::Inserted, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, and PKAPC.

Referenced by PspExitThread().

    00145                    :
    00146
    00147     This function flushes the APC queue selected by the specified processor
    00148     mode for the specified thread. An APC queue is flushed by removing the
    00149     listhead from the list, scanning the APC entries in the list, setting
    00150     their inserted variables to FALSE, and then returning the address of the
    00151     doubly linked list as the function value.
    00152
    00153 Arguments:
    00154
    00155     Thread - Supplies a pointer to a dispatcher object of type thread.
    00156
    00157     ApcMode - Supplies the processor mode of the APC queue that is to
    00158         be flushed.
    00159
    00160 Return Value:
    00161
    00162     The address of the first entry in the list of APC objects that were flushed
    00163     from the specified APC queue.
    00164
    00165 --*/
    00166
    00167 {
    00168
    00169     PKAPC Apc;
    00170     PLIST_ENTRY FirstEntry;
    00171     PLIST_ENTRY NextEntry;
    00172     KIRQL OldIrql;
    00173
    00174     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00175
    00176     //
    00177     // Raise IRQL to dispatcher level, lock dispatcher database, and
    00178     // lock the APC queue.
    00179     //
    00180
    00181     KiLockDispatcherDatabase(&OldIrql);
    00182     KiAcquireSpinLock(&Thread->ApcQueueLock);
    00183
    00184     //
    00185     // Get address of first APC in the list and check if the list is
    00186     // empty or contains entries that should be flushed. If entries
    00187     // should be flushed, then scan the list of APC objects and set their
    00188     // inserted state to FALSE.
    00189     //
    00190
    00191     FirstEntry = Thread->ApcState.ApcListHead[ApcMode].Flink;
    00192     if (FirstEntry == &Thread->ApcState.ApcListHead[ApcMode]) {
    00193         FirstEntry = (PLIST_ENTRY)NULL;
    00194
    00195     } else {
    00196         RemoveEntryList(&Thread->ApcState.ApcListHead[ApcMode]);
    00197         NextEntry = FirstEntry;
    00198         do {
    00199             Apc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry);
    00200             Apc->Inserted = FALSE;
    00201             NextEntry = NextEntry->Flink;
    00202         } while (NextEntry != FirstEntry);
    00203     }
    00204
    00205     //
    00206     // Unlock the APC queue, unlock the dispatcher database, lower IRQL to
    00207     // its previous value, and return address of first entry in list of APC
    00208     // objects that were flushed.
    00209     //
    00210
    00211     KiReleaseSpinLock(&Thread->ApcQueueLock);
    00212     KiUnlockDispatcherDatabase(OldIrql);
    00213     return FirstEntry;
    00214 }

HARDWARE_PTE KeFlushSingleTb | ( | IN PVOID | Virtual,
|  | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcesors,
|  | IN PHARDWARE_PTE | PtePointer,
|  | IN HARDWARE_PTE | PteValue
| ) |

Definition at line 420 of file alpha/flushtb.c.

References ASSERT, DISPATCH_LEVEL, IPI_INSTRUMENT_COUNT, KeGetCurrentPrcb, KiFlushSingleCallData, KiFlushSingleTb(), RECORD_CALL_DATA, and Virtual.

Referenced by Ki386UseSynchronousTbFlush(), MiCopyOnWrite(), MiDeletePte(), MiEliminateWorkingSetEntry(), MiEnablePagingOfDriverAtInit(), MiFlushDirtyBitsToPfn(), MiFlushPteList(), MiFlushTbAndCapture(), MiFlushUserPhysicalPteList(), MiFreeNonPagedPool(), MiInitMachineDependent(), MiMapPageToZeroInHyperSpace(), MiMapSinglePage(), MiProtectFreeNonPagedPool(), MiProtectSpecialPool(), MiResetVirtualMemory(), MiSetPageModified(), MiSetPagingOfDriver(), MiSetSystemCodeProtection(), MiUnmapImageHeaderInHyperSpace(), MiUnmapLockedPagesInUserSpace(), MmFreeSpecialPool(), MmMapUserAddressesToPage(), MmRemovePhysicalMemory(), MmSetAddressRangeModified(), and MmSetPageProtection().

    00430                    :
    00431
    00432     This function flushes a single entry from the translation buffer
    00433     on all processors that are currently running threads which are
    00434     children of the current process or flushes a single entry from
    00435     the translation buffer on all processors in the host configuration.
    00436
    00437 Arguments:
    00438
    00439     Virtual - Supplies a virtual address that is within the page whose
    00440         translation buffer entry is to be flushed.
    00441
    00442     Invalid - Supplies a boolean value that specifies the reason for
    00443         flushing the translation buffer.
    00444
    00445     AllProcessors - Supplies a boolean value that determines which
    00446         translation buffers are to be flushed.
    00447
    00448     PtePointer - Supplies a pointer to the page table entry which
    00449         receives the specified value.
    00450
    00451     PteValue - Supplies the the new page table entry value.
    00452
    00453 Return Value:
    00454
    00455     The previous contents of the specified page table entry is returned
    00456     as the function value.
    00457
    00458 --*/
    00459
    00460 {
    00461
    00462     KIRQL OldIrql;
    00463     HARDWARE_PTE OldPte;
    00464     PKPROCESS Process;
    00465     KAFFINITY TargetProcessors;
    00466     PKTHREAD Thread;
    00467
    00468     //
    00469     // Compute the target set of processors and send the flush single
    00470     // paramters to the target processors, if any, for execution.
    00471     //
    00472
    00473     if (AllProcessors != FALSE) {
    00474         OldIrql = KeRaiseIrqlToSynchLevel();
    00475         TargetProcessors = KeActiveProcessors;
    00476
    00477     } else {
    00478         KiLockContextSwap(&OldIrql);
    00479         Thread = KeGetCurrentThread();
    00480         Process = Thread->ApcState.Process;
    00481         TargetProcessors = Process->ActiveProcessors;
    00482         if (TargetProcessors != Process->RunOnProcessors) {
    00483             Process->ProcessSequence = KiMasterSequence - 1;
    00484         }
    00485     }
    00486
    00487     //
    00488     // Capture the previous contents of the page table entry and set the
    00489     // page table entry to the new value.
    00490     //
    00491
    00492     OldPte = *PtePointer;
    00493     *PtePointer = PteValue;
    00494     TargetProcessors &= PCR->NotMember;
    00495     if (TargetProcessors != 0) {
    00496         KiIpiSendPacket(TargetProcessors,
    00497                         KiFlushSingleTbTarget,
    00498                         (PVOID)Virtual,
    00499                         NULL,
    00500                         NULL);
    00501     }
    00502
    00503     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb);
    00504
    00505     //
    00506     // Flush the specified entry from the TB on the current processor.
    00507     //
    00508
    00509 //    KiFlushSingleTb(Invalid, Virtual);
    00510     __tbis(Virtual);
    00511
    00512     //
    00513     // Wait until all target processors have finished.
    00514     //
    00515
    00516     if (TargetProcessors != 0) {
    00517         KiIpiStallOnPacketTargets(TargetProcessors);
    00518     }
    00519
    00520     if (AllProcessors != FALSE) {
    00521         KeLowerIrql(OldIrql);
    00522
    00523     } else {
    00524         KiUnlockContextSwap(OldIrql);
    00525     }
    00526
    00527     //
    00528     // return the previous page table entry value.
    00529     //
    00530
    00531     return OldPte;
    00532 }

LOGICAL KeForceAttachProcess | ( | IN PKPROCESS | Process | ) |

ULONG KeForceResumeThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 688 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), and RESUME_INCREMENT.

Referenced by NtTerminateProcess(), NtTerminateThread(), PspExitNormalApc(), PspExitThread(), and PspTerminateProcess().

    00694                    :
    00695
    00696     This function forces resumption of thread execution if the thread is
    00697     suspended. If the specified thread is not suspended, then no operation
    00698     is performed.
    00699
    00700 Arguments:
    00701
    00702     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00703
    00704 Return Value:
    00705
    00706     The sum of the previous suspend count and the freeze count.
    00707
    00708 --*/
    00709
    00710 {
    00711
    00712     ULONG OldCount;
    00713     KIRQL OldIrql;
    00714
    00715     ASSERT_THREAD(Thread);
    00716     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00717
    00718     //
    00719     // Raise IRQL to dispatcher level and lock dispatcher database.
    00720     //
    00721
    00722     KiLockDispatcherDatabase(&OldIrql);
    00723
    00724     //
    00725     // Capture the current suspend count.
    00726     //
    00727
    00728     OldCount = Thread->SuspendCount + Thread->FreezeCount;
    00729
    00730     //
    00731     // If the thread is currently suspended, then force resumption of
    00732     // thread execution.
    00733     //
    00734
    00735     if (OldCount != 0) {
    00736         Thread->FreezeCount = 0;
    00737         Thread->SuspendCount = 0;
    00738         Thread->SuspendSemaphore.Header.SignalState += 1;
    00739         KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT);
    00740     }
    00741
    00742     //
    00743     // Unlock dispatcher database and lower IRQL to its previous
    00744     // value.
    00745     //
    00746
    00747     KiUnlockDispatcherDatabase(OldIrql);
    00748
    00749     //
    00750     // Return the previous suspend count.
    00751     //
    00752
    00753     return OldCount;
    00754 }

VOID KeFreezeAllThreads | ( | VOID |  | ) |

Definition at line 757 of file thredobj.c.

References _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, FALSE, _KTHREAD::FreezeCount, _KSEMAPHORE::Header, KeEnterCriticalRegion, KeGetCurrentThread, KiInsertQueueApc(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, _KAPC_STATE::Process, RESUME_INCREMENT, _DISPATCHER_HEADER::SignalState, _KTHREAD::SuspendApc, _KTHREAD::SuspendCount, _KTHREAD::SuspendSemaphore, _ETHREAD::ThreadListEntry, and _KPROCESS::ThreadListHead.

Referenced by DbgkpSuspendProcess().

    00763                    :
    00764
    00765     This function suspends the execution of all thread in the current
    00766     process except the current thread. If the freeze count overflows
    00767     the maximum suspend count, then a condition is raised.
    00768
    00769 Arguments:
    00770
    00771     None.
    00772
    00773 Return Value:
    00774
    00775     None.
    00776
    00777 --*/
    00778
    00779 {
    00780
    00781     PKTHREAD CurrentThread;
    00782     PLIST_ENTRY ListHead;
    00783     PLIST_ENTRY NextEntry;
    00784     PKPROCESS Process;
    00785     PKTHREAD Thread;
    00786     PETHREAD EThread;
    00787     ULONG OldCount;
    00788     KIRQL OldIrql;
    00789
    00790     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00791
    00792     //
    00793     // Get the address of the current thread object, the current process
    00794     // object, raise IRQL to dispatch level, lock dispatcher database,
    00795     // and freeze the execution of all threads in the process except the
    00796     // current thread.
    00797     //
    00798
    00799     CurrentThread = KeGetCurrentThread();
    00800     Process = CurrentThread->ApcState.Process;
    00801     KiLockDispatcherDatabase(&OldIrql);
    00802
    00803     //
    00804     // If the freeze count of the current thread is not zero, then there
    00805     // is another thread that is trying to freeze this thread. Unlock the
    00806     // dispatcher, lower IRQL to its previous value, allow the suspend
    00807     // APC to occur, then raise IRQL to dispatch level, lock the dispatcher
    00808     // database, and try again.
    00809     //
    00810
    00811     while (CurrentThread->FreezeCount != 0) {
    00812         KiUnlockDispatcherDatabase(OldIrql);
    00813         KiLockDispatcherDatabase(&OldIrql);
    00814     }
    00815
    00816     KeEnterCriticalRegion();
    00817
    00818     //
    00819     // Freeze all threads except the current thread.
    00820     //
    00821
    00822     ListHead = &Process->ThreadListHead;
    00823     NextEntry = ListHead->Flink;
    00824     do {
    00825
    00826         //
    00827         // Get the address of the next thread and suspend it if it is
    00828         // not the current thread.
    00829         //
    00830
    00831         Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
    00832         if (Thread != CurrentThread) {
    00833
    00834             EThread = (PETHREAD) Thread;
    00835             if ( EThread->ThreadListEntry.Flink == NULL ) {
    00836                 ;
    00837             } else {
    00838
    00839                 //
    00840                 // Increment the freeze count. If the thread was not previously
    00841                 // suspended, then queue the thread's suspend APC.
    00842                 //
    00843
    00844                 OldCount = Thread->FreezeCount;
    00845
    00846                 ASSERT(OldCount != MAXIMUM_SUSPEND_COUNT);
    00847
    00848                 Thread->FreezeCount += 1;
    00849                 if ((OldCount == 0) && (Thread->SuspendCount == 0)) {
    00850                     if (KiInsertQueueApc(&Thread->SuspendApc, RESUME_INCREMENT) == FALSE) {
    00851                         Thread->SuspendSemaphore.Header.SignalState -= 1;
    00852                     }
    00853                 }
    00854             }
    00855         }
    00856         NextEntry = NextEntry->Flink;
    00857     } while (NextEntry != ListHead);
    00858
    00859     //
    00860     // Unlock dispatcher database and lower IRQL to its previous
    00861     // value.
    00862     //
    00863
    00864     KiUnlockDispatcherDatabase(OldIrql);
    00865     return;
    00866 }

BOOLEAN KeFreezeExecution | ( | IN PKTRAP_FRAME | TrapFrame,
|  | IN PKEXCEPTION_FRAME | ExceptionFrame
| ) |

Definition at line 55 of file ke/debug.c.

References ClearMember, Count, FALSE, FREEZE_ACTIVE, FREEZE_BACKUP, FREEZE_FROZEN, FREEZE_OWNER, FREEZE_SKIPPED_PROCESSOR, FrozenState, HIGH_LEVEL, IPI_FREEZE, KeActiveProcessors, KeFindFirstSetRightMember, KeGetCurrentPrcb, KeRaiseIrql(), KeStallExecutionProcessor(), KiDisableInterrupts(), KiFreezeExecutionLock, KiFreezeFlag, KiFreezeLockBackup, KiFreezeOwner, KiIpiSend(), KiIpiServiceRoutine(), KiOldIrql, KiProcessorBlock, KiRestoreInterrupts(), KiTryToAcquireSpinLock(), TARGET_FROZEN, and TRUE.

Referenced by KdEnterDebugger().

    00062                    :
    00063
    00064     This function freezes the execution of all other processors in the host
    00065     configuration and then returns to the caller.
    00066
    00067 Arguments:
    00068
    00069     TrapFrame - Supplies a pointer to a trap frame that describes the
    00070         trap.
    00071
    00072     ExceptionFrame - Supplies a pointer to an exception frame that
    00073         describes the trap.
    00074
    00075 Return Value:
    00076
    00077     Previous interrupt enable.
    00078
    00079 --*/
    00080
    00081 {
    00082
    00083     BOOLEAN Enable;
    00084
    00085 #if !defined(NT_UP)
    00086
    00087     BOOLEAN Flag;
    00088     PKPRCB Prcb;
    00089     ULONG TargetSet;
    00090     ULONG BitNumber;
    00091     KIRQL OldIrql;
    00092
    00093 #if IDBG
    00094
    00095     ULONG Count = 30000;
    00096
    00097 #endif
    00098 #endif
    00099
    00100     //
    00101     // Disable interrupts.
    00102     //
    00103
    00104     Enable = KiDisableInterrupts();
    00105     KiFreezeFlag = FREEZE_FROZEN;
    00106
    00107 #if !defined(NT_UP)
    00108     //
    00109     // Raise IRQL to HIGH_LEVEL.
    00110     //
    00111
    00112     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    00113
    00114     if (FrozenState(KeGetCurrentPrcb()->IpiFrozen) == FREEZE_OWNER) {
    00115         //
    00116         // This processor already owns the freeze lock.
    00117         // Return without trying to re-acquire lock or without
    00118         // trying to IPI the other processors again
    00119         //
    00120
    00121         return Enable;
    00122     }
    00123
    00124
    00125     //
    00126     // Try to acquire the KiFreezeExecutionLock before sending the request.
    00127     // To prevent deadlock from occurring, we need to accept and process
    00128     // incoming FreexeExecution requests while we are waiting to acquire
    00129     // the FreezeExecutionFlag.
    00130     //
    00131
    00132     while (KiTryToAcquireSpinLock (&KiFreezeExecutionLock) == FALSE) {
    00133
    00134         //
    00135         // FreezeExecutionLock is busy.  Another processor may be trying
    00136         // to IPI us - go service any IPI.
    00137         //
    00138
    00139         KiRestoreInterrupts(Enable);
    00140         Flag = KiIpiServiceRoutine((PVOID)TrapFrame, (PVOID)ExceptionFrame);
    00141         KiDisableInterrupts();
    00142
    00143 #if IDBG
    00144
    00145         if (Flag != FALSE) {
    00146             Count = 30000;
    00147             continue;
    00148         }
    00149
    00150         KeStallExecutionProcessor (100);
    00151         if (!Count--) {
    00152             Count = 30000;
    00153             if (KiTryToAcquireSpinLock (&KiFreezeLockBackup) == TRUE) {
    00154                 KiFreezeFlag |= FREEZE_BACKUP;
    00155                 break;
    00156             }
    00157         }
    00158
    00159 #endif
    00160
    00161     }
    00162
    00163     //
    00164     // After acquiring the lock flag, we send Freeze request to each processor
    00165     // in the system (other than us) and wait for it to become frozen.
    00166     //
    00167
    00168     Prcb = KeGetCurrentPrcb();  // Do this after spinlock is acquired.
    00169     TargetSet = KeActiveProcessors & ~(1 << Prcb->Number);
    00170     if (TargetSet) {
    00171
    00172 #if IDBG
    00173         Count = 400;
    00174 #endif
    00175
    00176         KiFreezeOwner = Prcb;
    00177         Prcb->IpiFrozen = FREEZE_OWNER | FREEZE_ACTIVE;
    00178         Prcb->SkipTick  = TRUE;
    00179         KiIpiSend((KAFFINITY) TargetSet, IPI_FREEZE);
    00180
    00181         while (TargetSet != 0) {
    00182             BitNumber = KeFindFirstSetRightMember(TargetSet);
    00183             ClearMember(BitNumber, TargetSet);
    00184             Prcb = KiProcessorBlock[BitNumber];
    00185
    00186 #if IDBG
    00187
    00188             while (Prcb->IpiFrozen != TARGET_FROZEN) {
    00189                 if (Count == 0) {
    00190                     KiFreezeFlag |= FREEZE_SKIPPED_PROCESSOR;
    00191                     break;
    00192                 }
    00193
    00194                 KeStallExecutionProcessor (10000);
    00195                 Count--;
    00196             }
    00197
    00198 #else
    00199
    00200             while (Prcb->IpiFrozen != TARGET_FROZEN) {
    00201                 KeYieldProcessor();
    00202             }
    00203 #endif
    00204
    00205         }
    00206     }
    00207
    00208     //
    00209     // Save the old IRQL and return whether interrupts were previous enabled.
    00210     //
    00211
    00212     KiOldIrql = OldIrql;
    00213
    00214 #endif      // !defined(NT_UP)
    00215
    00216     return Enable;
    00217 }

BOOLEAN KeGetBugMessageText | ( | IN ULONG | MessageId,
|  | IN PANSI_STRING ReturnedString | OPTIONAL
| ) |

Definition at line 97 of file bugcheck.c.

References Buffer, EXCEPTION_EXECUTE_HANDLER, FALSE, InbvDisplayString(), MmMakeKernelResourceSectionWritable(), NULL, strlen(), TRUE, and USHORT.

Referenced by IopGetDumpStack(), and KeBugCheckEx().

    00101 {
    00102     ULONG   i;
    00103     PUCHAR  s;
    00104     PMESSAGE_RESOURCE_BLOCK MessageBlock;
    00105     PUCHAR Buffer;
    00106     BOOLEAN Result;
    00107
    00108     Result = FALSE;
    00109     try {
    00110         if (KiBugCodeMessages != NULL) {
    00111             MmMakeKernelResourceSectionWritable ();
    00112             MessageBlock = &KiBugCodeMessages->Blocks[0];
    00113             for (i = KiBugCodeMessages->NumberOfBlocks; i; i -= 1) {
    00114                 if (MessageId >= MessageBlock->LowId &&
    00115                     MessageId <= MessageBlock->HighId) {
    00116
    00117                     s = (PCHAR)KiBugCodeMessages + MessageBlock->OffsetToEntries;
    00118                     for (i = MessageId - MessageBlock->LowId; i; i -= 1) {
    00119                         s += ((PMESSAGE_RESOURCE_ENTRY)s)->Length;
    00120                     }
    00121
    00122                     Buffer = ((PMESSAGE_RESOURCE_ENTRY)s)->Text;
    00123
    00124                     i = strlen(Buffer) - 1;
    00125                     while (i > 0 && (Buffer[i] == '\n'  ||
    00126                                      Buffer[i] == '\r'  ||
    00127                                      Buffer[i] == 0
    00128                                     )
    00129                           ) {
    00130                         if (!ARGUMENT_PRESENT( ReturnedString )) {
    00131                             Buffer[i] = 0;
    00132                         }
    00133                         i -= 1;
    00134                     }
    00135
    00136                     if (!ARGUMENT_PRESENT( ReturnedString )) {
    00137                         InbvDisplayString(Buffer);
    00138                         }
    00139                     else {
    00140                         ReturnedString->Buffer = Buffer;
    00141                         ReturnedString->Length = (USHORT)(i+1);
    00142                         ReturnedString->MaximumLength = (USHORT)(i+1);
    00143                     }
    00144                     Result = TRUE;
    00145                     break;
    00146                 }
    00147                 MessageBlock += 1;
    00148             }
    00149         }
    00150     } except ( EXCEPTION_EXECUTE_HANDLER ) {
    00151         ;
    00152     }
    00153
    00154     return Result;
    00155 }

VOID KeGetNonVolatileContextPointers | ( | IN PKNONVOLATILE_CONTEXT_POINTERS | NonVolatileContext | ) |

NTKERNELAPI VOID KeInitializeApc | ( | IN PRKAPC | Apc,
|  | IN PRKTHREAD | Thread,
|  | IN KAPC_ENVIRONMENT | Environment,
|  | IN PKKERNEL_ROUTINE | KernelRoutine,
|  | IN PKRUNDOWN_ROUTINE RundownRoutine | OPTIONAL,
|  | IN PKNORMAL_ROUTINE NormalRoutine | OPTIONAL,
|  | IN KPROCESSOR_MODE ProcessorMode | OPTIONAL,
|  | IN PVOID NormalContext | OPTIONAL
| ) |

NTKERNELAPI VOID KeInitializeDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue | ) |

Definition at line 40 of file devquobj.c.

References DeviceQueueObject, FALSE, KDEVICE_QUEUE, KeInitializeSpinLock(), and PKDEVICE_QUEUE.

Referenced by IoCreateController(), and IoCreateDevice().

    00046                    :
    00047
    00048     This function initializes a kernel device queue object.
    00049
    00050 Arguments:
    00051
    00052     DeviceQueue - Supplies a pointer to a control object of type device
    00053         queue.
    00054
    00055     SpinLock - Supplies a pointer to an executive spin lock.
    00056
    00057 Return Value:
    00058
    00059     None.
    00060
    00061 --*/
    00062
    00063 {
    00064
    00065     //
    00066     // Initialize standard control object header.
    00067     //
    00068
    00069     DeviceQueue->Type = DeviceQueueObject;
    00070     DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
    00071
    00072     //
    00073     // Initialize the device queue list head, spin lock, and busy indicator.
    00074     //
    00075
    00076     InitializeListHead(&DeviceQueue->DeviceListHead);
    00077     KeInitializeSpinLock(&DeviceQueue->Lock);
    00078     DeviceQueue->Busy = FALSE;
    00079     return;
    00080 }

NTKERNELAPI VOID KeInitializeDpc | ( | IN PRKDPC | Dpc,
|  | IN PKDEFERRED_ROUTINE | DeferredRoutine,
|  | IN PVOID | DeferredContext
| ) |

Definition at line 39 of file dpcobj.c.

References DpcObject, MediumImportance, NULL, PKDEFERRED_ROUTINE, and PRKDPC.

Referenced by CcInitializeCacheManager(), CmpWorker(), IoInitSystem(), IopErrorLogQueueRequest(), IovpInternalDeferredCompletion(), KdInitSystem(), KiInitializeKernel(), KiInitSystem(), MiInitializeSpecialPoolCriteria(), MmInitSystem(), NtCreateTimer(), and VdmpDelayInterrupt().

    00047                    :
    00048
    00049     This function initializes a kernel DPC object. The deferred routine
    00050     and context parameter are stored in the DPC object.
    00051
    00052 Arguments:
    00053
    00054     Dpc - Supplies a pointer to a control object of type DPC.
    00055
    00056     DeferredRoutine - Supplies a pointer to a function that is called when
    00057         the DPC object is removed from the current processor's DPC queue.
    00058
    00059     DeferredContext - Supplies a pointer to an arbitrary data structure which is
    00060         to be passed to the function specified by the DeferredRoutine parameter.
    00061
    00062 Return Value:
    00063
    00064     None.
    00065
    00066 --*/
    00067
    00068 {
    00069
    00070     //
    00071     // Initialize standard control object header.
    00072     //
    00073
    00074     Dpc->Type = DpcObject;
    00075     Dpc->Number = 0;
    00076     Dpc->Importance = MediumImportance;
    00077
    00078     //
    00079     // Initialize deferred routine address and deferred context parameter.
    00080     //
    00081
    00082     Dpc->DeferredRoutine = DeferredRoutine;
    00083     Dpc->DeferredContext = DeferredContext;
    00084     Dpc->Lock = NULL;
    00085     return;
    00086 }

VOID KeInitializeEventPair | ( | IN PKEVENT_PAIR | EventPair | ) |

Definition at line 96 of file eventobj.c.

References EventPairObject, FALSE, KeInitializeEvent, KEVENT_PAIR, PKEVENT_PAIR, and USHORT.

Referenced by NtCreateEventPair().

    00102                    :
    00103
    00104     This function initializes a kernel event pair object. A kernel event
    00105     pair object contains two separate synchronization event objects that
    00106     are used to provide a fast interprocess synchronization capability.
    00107
    00108 Arguments:
    00109
    00110     EventPair - Supplies a pointer to a control object of type event pair.
    00111
    00112 Return Value:
    00113
    00114     None.
    00115
    00116 --*/
    00117
    00118 {
    00119
    00120     //
    00121     // Initialize the type and size of the event pair object and initialize
    00122     // the two event object as synchronization events with an initial state
    00123     // of FALSE.
    00124     //
    00125
    00126     EventPair->Type = (USHORT)EventPairObject;
    00127     EventPair->Size = sizeof(KEVENT_PAIR);
    00128     KeInitializeEvent(&EventPair->EventLow, SynchronizationEvent, FALSE);
    00129     KeInitializeEvent(&EventPair->EventHigh, SynchronizationEvent, FALSE);
    00130     return;
    00131 }

NTKERNELAPI VOID KeInitializeInterrupt | ( | IN PKINTERRUPT | Interrupt,
|  | IN PKSERVICE_ROUTINE | ServiceRoutine,
|  | IN PVOID | ServiceContext,
|  | IN PKSPIN_LOCK SpinLock | OPTIONAL,
|  | IN ULONG | Vector,
|  | IN KIRQL | Irql,
|  | IN KIRQL | SynchronizeIrql,
|  | IN KINTERRUPT_MODE | InterruptMode,
|  | IN BOOLEAN | ShareVector,
|  | IN CCHAR | ProcessorNumber,
|  | IN BOOLEAN | FloatingSave
| ) |

Definition at line 32 of file alpha/intobj.c.

References FALSE, and InterruptObject.

Referenced by IoConnectInterrupt().

    00048                    :
    00049
    00050     This function initializes a kernel interrupt object. The service routine,
    00051     service context, spin lock, vector, IRQL, Synchronized IRQL, and floating
    00052     context save flag are initialized.
    00053
    00054 Arguments:
    00055
    00056     Interrupt - Supplies a pointer to a control object of type interrupt.
    00057
    00058     ServiceRoutine - Supplies a pointer to a function that is to be
    00059         executed when an interrupt occurs via the specified interrupt
    00060         vector.
    00061
    00062     ServiceContext - Supplies a pointer to an arbitrary data structure which is
    00063         to be passed to the function specified by the ServiceRoutine parameter.
    00064
    00065     SpinLock - Supplies an optional pointer to an executive spin lock.
    00066
    00067     Vector - Supplies the index of the entry in the Interrupt Dispatch Table
    00068         that is to be associated with the ServiceRoutine function.
    00069
    00070     Irql - Supplies the request priority of the interrupting source.
    00071
    00072     SynchronizeIrql - The request priority that the interrupt should be
    00073         synchronized with.
    00074
    00075     InterruptMode - Supplies the mode of the interrupt; LevelSensitive or
    00076         Latched.
    00077
    00078     ShareVector - Supplies a boolean value that specifies whether the
    00079         vector can be shared with other interrupt objects or not.  If FALSE
    00080         then the vector may not be shared, if TRUE it may be.
    00081         Latched.
    00082
    00083     ProcessorNumber - Supplies the number of the processor to which the
    00084         interrupt will be connected.
    00085
    00086     FloatingSave - Supplies a boolean value that determines whether the
    00087         floating point registers and pipe line are to be saved before calling
    00088         the ServiceRoutine function.
    00089
    00090 Return Value:
    00091
    00092     None.
    00093
    00094 --*/
    00095
    00096 {
    00097
    00098     LONG Index;
    00099
    00100     //
    00101     // Initialize standard control object header.
    00102     //
    00103
    00104     Interrupt->Type = InterruptObject;
    00105     Interrupt->Size = sizeof(KINTERRUPT);
    00106
    00107     //
    00108     // Initialize the address of the service routine, the service context,
    00109     // the address of the spin lock, the address of the actual spin lock
    00110     // that will be used, the vector number, the IRQL of the interrupting
    00111     // source, the Synchronized IRQL of the interrupt object, the interrupt
    00112     // mode, the processor number, and the floating context save flag.
    00113     //
    00114
    00115     Interrupt->ServiceRoutine = ServiceRoutine;
    00116     Interrupt->ServiceContext = ServiceContext;
    00117
    00118     if (ARGUMENT_PRESENT(SpinLock)) {
    00119         Interrupt->ActualLock = SpinLock;
    00120     } else {
    00121         Interrupt->SpinLock = 0;
    00122         Interrupt->ActualLock = &Interrupt->SpinLock;
    00123     }
    00124
    00125     Interrupt->Vector = Vector;
    00126     Interrupt->Irql = Irql;
    00127     Interrupt->SynchronizeIrql = SynchronizeIrql;
    00128     Interrupt->Mode = InterruptMode;
    00129     Interrupt->ShareVector = ShareVector;
    00130     Interrupt->Number = ProcessorNumber;
    00131     Interrupt->FloatingSave = FloatingSave;
    00132
    00133     //
    00134     // Copy the interrupt dispatch code template into the interrupt object
    00135     // and flush the dcache on all processors that the current thread can
    00136     // run on to ensure that the code is actually in memory.
    00137     //
    00138
    00139     for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) {
    00140         Interrupt->DispatchCode[Index] = KiInterruptTemplate[Index];
    00141     }
    00142
    00143     KeSweepIcache(FALSE);
    00144
    00145     //
    00146     // Set the connected state of the interrupt object to FALSE.
    00147     //
    00148
    00149     Interrupt->Connected = FALSE;
    00150     return;
    00151 }

NTKERNELAPI VOID KeInitializeMutant | ( | IN PRKMUTANT | Mutant,
|  | IN BOOLEAN | InitialOwner
| ) |

Definition at line 40 of file mutntobj.c.

References FALSE, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), _KTHREAD::MutantListHead, MutantObject, NULL, and TRUE.

Referenced by MmInitSystem(), NtCreateMutant(), and ObInitSystem().

    00047                    :
    00048
    00049     This function initializes a kernel mutant object.
    00050
    00051 Arguments:
    00052
    00053     Mutant - Supplies a pointer to a dispatcher object of type mutant.
    00054
    00055     InitialOwner - Supplies a boolean value that determines whether the
    00056         current thread is to be the initial owner of the mutant object.
    00057
    00058 Return Value:
    00059
    00060     None.
    00061
    00062 --*/
    00063
    00064 {
    00065
    00066     PLIST_ENTRY ListEntry;
    00067     KIRQL OldIrql;
    00068     PRKTHREAD Thread;
    00069
    00070     //
    00071     // Initialize standard dispatcher object header, set the owner thread to
    00072     // NULL, set the abandoned state to FALSE, and set the APC disable count
    00073     // to zero (this is the only thing that distinguishes a mutex from a mutant).
    00074     //
    00075
    00076     Mutant->Header.Type = MutantObject;
    00077     Mutant->Header.Size = sizeof(KMUTANT) / sizeof(LONG);
    00078     if (InitialOwner == TRUE) {
    00079         Thread = KeGetCurrentThread();
    00080         Mutant->Header.SignalState = 0;
    00081         Mutant->OwnerThread = Thread;
    00082         KiLockDispatcherDatabase(&OldIrql);
    00083         ListEntry = Thread->MutantListHead.Blink;
    00084         InsertHeadList(ListEntry, &Mutant->MutantListEntry);
    00085         KiUnlockDispatcherDatabase(OldIrql);
    00086
    00087     } else {
    00088         Mutant->Header.SignalState = 1;
    00089         Mutant->OwnerThread = (PKTHREAD)NULL;
    00090     }
    00091
    00092     InitializeListHead(&Mutant->Header.WaitListHead);
    00093     Mutant->Abandoned = FALSE;
    00094     Mutant->ApcDisable = 0;
    00095     return;
    00096 }

NTKERNELAPI VOID KeInitializeMutex | ( | IN PRKMUTEX | Mutex,
|  | IN ULONG | Level
| ) |

VOID KeInitializeProcess | ( | IN PRKPROCESS | Process,
|  | IN KPRIORITY | Priority,
|  | IN KAFFINITY | Affinity,
|  | IN ULONG_PTR | DirectoryTableBase[2],
|  | IN BOOLEAN | Enable
| ) |

Definition at line 63 of file procobj.c.

References ProcessInMemory, ProcessObject, and THREAD_QUANTUM.

Referenced by KiInitializeKernel(), and PspCreateProcess().

    00073                    :
    00074
    00075     This function initializes a kernel process object. The base priority,
    00076     affinity, and page frame numbers for the process page table directory
    00077     and hyper space are stored in the process object.
    00078
    00079     N.B. It is assumed that the process object is zeroed.
    00080
    00081 Arguments:
    00082
    00083     Process - Supplies a pointer to a dispatcher object of type process.
    00084
    00085     BasePriority - Supplies the base priority of the process.
    00086
    00087     Affinity - Supplies the set of processors on which children threads
    00088         of the process can execute.
    00089
    00090     DirectoryTableBase - Supplies a pointer to an array whose fist element
    00091         is the value that is to be loaded into the Directory Table Base
    00092         register when a child thread is dispatched for execution and whose
    00093         second element contains the page table entry that maps hyper space.
    00094
    00095     Enable - Supplies a boolean value that determines the default
    00096         handling of data alignment exceptions for child threads. A value
    00097         of TRUE causes all data alignment exceptions to be automatically
    00098         handled by the kernel. A value of FALSE causes all data alignment
    00099         exceptions to be actually raised as exceptions.
    00100
    00101 Return Value:
    00102
    00103     None.
    00104
    00105 --*/
    00106
    00107 {
    00108
    00109     //
    00110     // Initialize the standard dispatcher object header and set the initial
    00111     // signal state of the process object.
    00112     //
    00113
    00114     Process->Header.Type = ProcessObject;
    00115     Process->Header.Size = sizeof(KPROCESS) / sizeof(LONG);
    00116     InitializeListHead(&Process->Header.WaitListHead);
    00117
    00118     //
    00119     // Initialize the base priority, affinity, directory table base values,
    00120     // autoalignment, and stack count.
    00121     //
    00122     // N.B. The distinguished value MAXSHORT is used to signify that no
    00123     //      threads have been created for the process.
    00124     //
    00125
    00126     Process->BasePriority = (SCHAR)BasePriority;
    00127     Process->Affinity = Affinity;
    00128     Process->AutoAlignment = Enable;
    00129     Process->DirectoryTableBase[0] = DirectoryTableBase[0];
    00130     Process->DirectoryTableBase[1] = DirectoryTableBase[1];
    00131     Process->StackCount = MAXSHORT;
    00132
    00133     //
    00134     // Initialize the stack count, profile listhead, ready queue list head,
    00135     // accumulated runtime, process quantum, thread quantum, and thread list
    00136     // head.
    00137     //
    00138
    00139     InitializeListHead(&Process->ProfileListHead);
    00140     InitializeListHead(&Process->ReadyListHead);
    00141     InitializeListHead(&Process->ThreadListHead);
    00142     Process->ThreadQuantum = THREAD_QUANTUM;
    00143
    00144     //
    00145     // Initialize the process state and set the thread processor selection
    00146     // seed.
    00147     //
    00148
    00149     Process->State = ProcessInMemory;
    00150     Process->ThreadSeed = (UCHAR)KiQueryLowTickCount();
    00151
    00152     //
    00153     // Initialize IopmBase and Iopl flag for this process (i386 only)
    00154     //
    00155
    00156 #ifdef i386
    00157
    00158     Process->IopmOffset = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
    00159
    00160 #endif
    00161
    00162     return;
    00163 }

VOID KeInitializeProfile | ( | IN PKPROFILE | Profile,
|  | IN PKPROCESS Process | OPTIONAL,
|  | IN PVOID | RangeBase,
|  | IN SIZE_T | RangeSize,
|  | IN ULONG | BucketSize,
|  | IN ULONG | Segment,
|  | IN KPROFILE_SOURCE | ProfileSource,
|  | IN KAFFINITY | Affinity
| ) |

Definition at line 69 of file profobj.c.

References ASSERT, FALSE, KeActiveProcessors, NULL, and ProfileObject.

Referenced by NtStartProfile().

    00082                    :
    00083
    00084     This function initializes a kernel profile object. The process,
    00085     address range, bucket size, and buffer are set. The profile is
    00086     set to the stopped state.
    00087
    00088 Arguments:
    00089
    00090     Profile - Supplies a pointer to control object of type profile.
    00091
    00092     Process - Supplies an optional pointer to a process object that
    00093         describes the address space to profile. If not specified,
    00094         then all address spaces are included in the profile.
    00095
    00096     RangeBase - Supplies the address of the first byte of the address
    00097         range for which profiling information is to be collected.
    00098
    00099     RangeSize - Supplies the size of the address range for which profiling
    00100         information is to be collected.  The RangeBase and RangeSize
    00101         parameters are interpreted such that RangeBase <= address <
    00102         RangeBase + RangeSize generates a profile hit.
    00103
    00104     BucketSize - Supplies the log base 2 of the size of a profiling bucket.
    00105         Thus, BucketSize = 2 yields 4-byte buckets, BucketSize = 7 yields
    00106         128-byte buckets.
    00107
    00108     Segment - Supplies the non-Flat code segment to profile.  If this
    00109         is zero, then the flat profiling is done.  This will only
    00110         be non-zero on an x86 machine.
    00111
    00112     ProfileSource - Supplies the profile interrupt source.
    00113
    00114     ProfileAffinity - Supplies the set of processor to count hits for.
    00115
    00116 Return Value:
    00117
    00118     None.
    00119
    00120 --*/
    00121
    00122 {
    00123
    00124 #if !defined(i386)
    00125
    00126     ASSERT(Segment == 0);
    00127
    00128 #endif
    00129
    00130     //
    00131     // Initialize the standard control object header.
    00132     //
    00133
    00134     Profile->Type = ProfileObject;
    00135     Profile->Size = sizeof(KPROFILE);
    00136
    00137     //
    00138     // Initialize the process address space, range base, range limit,
    00139     // bucket shift count, and set started FALSE.
    00140     //
    00141
    00142     if (ARGUMENT_PRESENT(Process)) {
    00143         Profile->Process = Process;
    00144
    00145     } else {
    00146         Profile->Process = NULL;
    00147     }
    00148
    00149     Profile->RangeBase = RangeBase;
    00150     Profile->RangeLimit = (PUCHAR)RangeBase + RangeSize;
    00151     Profile->BucketShift = BucketSize - 2;
    00152     Profile->Started = FALSE;
    00153     Profile->Segment = Segment;
    00154     Profile->Source = (CSHORT)ProfileSource;
    00155     Profile->Affinity = ProfileAffinity & KeActiveProcessors;
    00156     if (Profile->Affinity == 0) {
    00157         Profile->Affinity = KeActiveProcessors;
    00158     }
    00159     return;
    00160 }

NTKERNELAPI VOID KeInitializeQueue | ( | IN PRKQUEUE | Queue,
|  | IN ULONG Count | OPTIONAL
| ) |

Definition at line 36 of file queueobj.c.

References Count, KeNumberProcessors, and QueueObject.

Referenced by ExpWorkerInitialization(), FsRtlInitializeWorkerThread(), and NtCreateIoCompletion().

    00043                    :
    00044
    00045     This function initializes a kernel queue object.
    00046
    00047 Arguments:
    00048
    00049     Queue - Supplies a pointer to a dispatcher object of type event.
    00050
    00051     Count - Supplies the target maximum number of threads that should
    00052         be concurrently active. If this parameter is not specified,
    00053         then the number of processors is used.
    00054
    00055 Return Value:
    00056
    00057     None.
    00058
    00059 --*/
    00060
    00061 {
    00062
    00063     //
    00064     // Initialize standard dispatcher object header and set initial
    00065     // state of queue object.
    00066     //
    00067
    00068     Queue->Header.Type = QueueObject;
    00069     Queue->Header.Size = sizeof(KQUEUE) / sizeof(LONG);
    00070     Queue->Header.SignalState = 0;
    00071     InitializeListHead(&Queue->Header.WaitListHead);
    00072
    00073     //
    00074     // Initialize queue listhead, the thread list head, the current number
    00075     // of threads, and the target maximum number of threads.
    00076     //
    00077
    00078     InitializeListHead(&Queue->EntryListHead);
    00079     InitializeListHead(&Queue->ThreadListHead);
    00080     Queue->CurrentCount = 0;
    00081     if (ARGUMENT_PRESENT((PVOID)(ULONG_PTR)Count)) {
    00082         Queue->MaximumCount = Count;
    00083
    00084     } else {
    00085         Queue->MaximumCount = KeNumberProcessors;
    00086     }
    00087
    00088     return;
    00089 }

NTKERNELAPI VOID KeInitializeSemaphore | ( | IN PRKSEMAPHORE | Semaphore,
|  | IN LONG | Count,
|  | IN LONG | Limit
| ) |

Definition at line 39 of file semphobj.c.

References Count, and SemaphoreObject.

Referenced by DoResourceTest(), ExAcquireResourceSharedLite(), ExAcquireSharedStarveExclusive(), ExAcquireSharedWaitForExclusive(), ExInitializeResource(), ExReinitializeResourceLite(), FsRtlInitSystem(), InitializePool(), IoInitSystem(), KeInitializeThread(), LpcpInitializePortQueue(), MiSectionInitialization(), NtCreateSemaphore(), obtest(), PspCreateThread(), and SmbTraceThreadEntry().

    00047                    :
    00048
    00049     This function initializes a kernel semaphore object. The initial
    00050     count and limit of the object are set to the specified values.
    00051
    00052 Arguments:
    00053
    00054     Semaphore - Supplies a pointer to a dispatcher object of type
    00055         semaphore.
    00056
    00057     Count - Supplies the initial count value to be assigned to the
    00058         semaphore.
    00059
    00060     Limit - Supplies the maximum count value that the semaphore
    00061         can attain.
    00062
    00063 Return Value:
    00064
    00065     None.
    00066
    00067 --*/
    00068
    00069 {
    00070
    00071     //
    00072     // Initialize standard dispatcher object header and set initial
    00073     // count and maximum count values.
    00074     //
    00075
    00076     Semaphore->Header.Type = SemaphoreObject;
    00077     Semaphore->Header.Size = sizeof(KSEMAPHORE) / sizeof(LONG);
    00078     Semaphore->Header.SignalState = Count;
    00079     InitializeListHead(&Semaphore->Header.WaitListHead);
    00080     Semaphore->Limit = Limit;
    00081     return;
    00082 }

NTKERNELAPI VOID NTAPI KeInitializeSpinLock | ( | IN PKSPIN_LOCK | SpinLock | ) |

| Referenced by CcInitializeCacheManager(), CcInitializeCacheMap(), CcInitializeVacbs(), ExCreateCallback(), ExCreateDebugLog(), ExInitializeCallData(), ExInitializeNPagedLookasideList(), ExInitializeResource(), ExInitializeResourceLite(), ExLuidInitialization(), ExpResourceInitialization(), ExpTimerInitialization(), ExReinitializeResourceLite(), FsRtlPrivateInitializeFileLock(), InitializePool(), IoErrInitSystem(), IoInitializeRemoveLockEx(), IoInitSystem(), IopInitializePlugPlayServices(), IoVerifierInit(), IovpTrackingDataCreateAndLock(), IovpTrackingDataInit(), KeInitializeDeviceQueue(), KeInitializeInterrupt(), KeInitializeThread(), KiAmdK6InitializeMTRR(), KiInitializeAbios(), KiInitializeKernel(), KiInitializeMTRR(), KiInitSystem(), MemPrintInitialize(), MiInitializeDriverVerifierList(), MiInitializeIoTrackers(), MiInitializeLoadedModuleList(), MiInitMachineDependent(), MiSectionInitialization(), MiSessionCreateInternal(), MmCreateProcessAddressSpace(), MmInitializeProcessAddressSpace(), MmInitSystem(), NtCreateTimer(), NtSetInformationProcess(), ObInitSystem(), PspCreateProcess(), PspCreateThread(), PspSetQuotaLimits(), RtlAllocateRemoveLock(), SmbTraceInitialize(), SmbTraceThreadEntry(), UdfMountVolume(), VdmpInitialize(), and ViInitializeEntry().

VOID KeInitializeThread | ( | IN PKTHREAD | Thread,
|  | IN PVOID | KernelStack,
|  | IN PKSYSTEM_ROUTINE | SystemRoutine,
|  | IN PKSTART_ROUTINE StartRoutine | OPTIONAL,
|  | IN PVOID StartContext | OPTIONAL,
|  | IN PCONTEXT ContextFrame | OPTIONAL,
|  | IN PVOID Teb | OPTIONAL,
|  | IN PKPROCESS | Process
| ) |

Definition at line 43 of file thredobj.c.

References FALSE, _KTIMER::Header, Index, Initialized, KeInitializeApc(), KeInitializeSemaphore(), KeInitializeSpinLock(), KeInitializeTimer(), KeNumberProcessors, KernelMode, KeServiceDescriptorTable, KiInitializeContextThread(), KiLockDispatcherDatabase, KiSuspendNop(), KiSuspendThread(), KiUnlockDispatcherDatabase(), L, NULL, _KWAIT_BLOCK::Object, OriginalApcEnvironment, PKKERNEL_ROUTINE, PKRUNDOWN_ROUTINE, THREAD_WAIT_OBJECTS, ThreadObject, TIMER_WAIT_BLOCK, TRUE, UserMode, _KWAIT_BLOCK::WaitKey, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, and _KWAIT_BLOCK::WaitType.

Referenced by KiInitializeKernel(), and PspCreateThread().

    00056                    :
    00057
    00058     This function initializes a thread object. The priority, affinity,
    00059     and initial quantum are taken from the parent process object. The
    00060     thread object is inserted at the end of the thread list for the
    00061     parent process.
    00062
    00063     N.B. This routine is carefully written so that if an access violation
    00064         occurs while reading the specified context frame, then no kernel
    00065         data structures will have been modified. It is the responsibility
    00066         of the caller to handle the exception and provide necessary clean
    00067         up.
    00068
    00069     N.B. It is assumed that the thread object is zeroed.
    00070
    00071 Arguments:
    00072
    00073     Thread - Supplies a pointer to a dispatcher object of type thread.
    00074
    00075     KernelStack - Supplies a pointer to the base of a kernel stack on which
    00076         the context frame for the thread is to be constructed.
    00077
    00078     SystemRoutine - Supplies a pointer to the system function that is to be
    00079         called when the thread is first scheduled for execution.
    00080
    00081     StartRoutine - Supplies an optional pointer to a function that is to be
    00082         called after the system has finished initializing the thread. This
    00083         parameter is specified if the thread is a system thread and will
    00084         execute totally in kernel mode.
    00085
    00086     StartContext - Supplies an optional pointer to an arbitrary data structure
    00087         which will be passed to the StartRoutine as a parameter. This
    00088         parameter is specified if the thread is a system thread and will
    00089         execute totally in kernel mode.
    00090
    00091     ContextFrame - Supplies an optional pointer a context frame which contains
    00092         the initial user mode state of the thread. This parameter is specified
    00093         if the thread is a user thread and will execute in user mode. If this
    00094         parameter is not specified, then the Teb parameter is ignored.
    00095
    00096     Teb - Supplies an optional pointer to the user mode thread environment
    00097         block. This parameter is specified if the thread is a user thread and
    00098         will execute in user mode. This parameter is ignored if the ContextFrame
    00099         parameter is not specified.
    00100
    00101     Process - Supplies a pointer to a control object of type process.
    00102
    00103 Return Value:
    00104
    00105     None.
    00106
    00107 --*/
    00108
    00109 {
    00110
    00111     ULONG Index;
    00112     KIRQL OldIrql;
    00113     PKTIMER Timer;
    00114     PKWAIT_BLOCK WaitBlock;
    00115
    00116     //
    00117     // Initialize the standard dispatcher object header and set the initial
    00118     // state of the thread object.
    00119     //
    00120
    00121     Thread->Header.Type = ThreadObject;
    00122     Thread->Header.Size = sizeof(KTHREAD) / sizeof(LONG);
    00123     InitializeListHead(&Thread->Header.WaitListHead);
    00124
    00125     //
    00126     // Initialize the owned mutant listhead.
    00127     //
    00128
    00129     InitializeListHead(&Thread->MutantListHead);
    00130
    00131     //
    00132     // Initialize the thread field of all builtin wait blocks.
    00133     //
    00134
    00135     for (Index = 0; Index < (THREAD_WAIT_OBJECTS + 1); Index += 1) {
    00136         Thread->WaitBlock[Index].Thread = Thread;
    00137     }
    00138
    00139     //
    00140     // Initialize the alerted, preempted, debugactive, autoalignment,
    00141     // kernel stack resident, enable kernel stack swap, and process
    00142     // ready queue boolean values.
    00143     //
    00144     // N.B. Only nonzero values are initialized.
    00145     //
    00146
    00147     Thread->AutoAlignment = Process->AutoAlignment;
    00148     Thread->EnableStackSwap = TRUE;
    00149     Thread->KernelStackResident = TRUE;
    00150
    00151     //
    00152     // Set the system service table pointer to the address of the static
    00153     // system service descriptor table. If the thread is later converted
    00154     // to a Win32 thread this pointer will be change to a pointer to the
    00155     // shadow system service descriptor table.
    00156     //
    00157
    00158     Thread->ServiceTable = (PVOID)&KeServiceDescriptorTable[0];
    00159
    00160     //
    00161     // Initialize the APC state pointers, the current APC state, the saved
    00162     // APC state, and enable APC queuing.
    00163     //
    00164
    00165     Thread->ApcStatePointer[0] = &Thread->ApcState;
    00166     Thread->ApcStatePointer[1] = &Thread->SavedApcState;
    00167     InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
    00168     InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
    00169     Thread->ApcState.Process = Process;
    00170     Thread->ApcQueueable = TRUE;
    00171
    00172     //
    00173     // Initialize the kernel mode suspend APC and the suspend semaphore object.
    00174     // and the builtin wait timeout timer object.
    00175     //
    00176
    00177     KeInitializeApc(&Thread->SuspendApc,
    00178                     Thread,
    00179                     OriginalApcEnvironment,
    00180                     (PKKERNEL_ROUTINE)KiSuspendNop,
    00181                     (PKRUNDOWN_ROUTINE)NULL,
    00182                     KiSuspendThread,
    00183                     KernelMode,
    00184                     NULL);
    00185
    00186     KeInitializeSemaphore(&Thread->SuspendSemaphore, 0L, 2L);
    00187
    00188     //
    00189     // Initialize the builtin timer trimer wait wait block.
    00190     //
    00191     // N.B. This is the only time the wait block is initialized sincs this
    00192     //      information is constant.
    00193     //
    00194
    00195     Timer = &Thread->Timer;
    00196     KeInitializeTimer(Timer);
    00197     WaitBlock = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
    00198     WaitBlock->Object = Timer;
    00199     WaitBlock->WaitKey = (CSHORT)STATUS_TIMEOUT;
    00200     WaitBlock->WaitType = WaitAny;
    00201     WaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
    00202     WaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
    00203
    00204     //
    00205     // Initialize the APC queue spinlock.
    00206     //
    00207
    00208     KeInitializeSpinLock(&Thread->ApcQueueLock);
    00209
    00210     //
    00211     // Initialize the Thread Environment Block (TEB) pointer (can be NULL).
    00212     //
    00213
    00214     Thread->Teb = Teb;
    00215
    00216     //
    00217     // Set the initial kernel stack and the initial thread context.
    00218     //
    00219
    00220     Thread->InitialStack = KernelStack;
    00221     Thread->StackBase = KernelStack;
    00222     Thread->StackLimit = (PVOID)((ULONG_PTR)KernelStack - KERNEL_STACK_SIZE);
    00223     KiInitializeContextThread(Thread,
    00224                               SystemRoutine,
    00225                               StartRoutine,
    00226                               StartContext,
    00227                               ContextFrame);
    00228
    00229     //
    00230     // Set the base thread priority, the thread priority, the thread affinity,
    00231     // the thread quantum, and the scheduling state.
    00232     //
    00233
    00234     Thread->BasePriority = Process->BasePriority;
    00235     Thread->Priority = Thread->BasePriority;
    00236     Thread->Affinity = Process->Affinity;
    00237     Thread->UserAffinity = Process->Affinity;
    00238     Thread->SystemAffinityActive = FALSE;
    00239     Thread->Quantum = Process->ThreadQuantum;
    00240     Thread->State = Initialized;
    00241     Thread->DisableBoost = Process->DisableBoost;
    00242
    00243 #ifdef i386
    00244
    00245     Thread->Iopl = Process->Iopl;
    00246
    00247 #endif
    00248
    00249     //
    00250     // Lock the dispatcher database, insert the thread in the process
    00251     // thread list, increment the kernel stack count, and unlock the
    00252     // dispatcher database.
    00253     //
    00254     // N.B. The distinguished value MAXSHORT is used to signify that no
    00255     //      threads have been created for a process.
    00256     //
    00257
    00258     KiLockDispatcherDatabase(&OldIrql);
    00259     InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
    00260     if (Process->StackCount == MAXSHORT) {
    00261         Process->StackCount = 1;
    00262
    00263     } else {
    00264         Process->StackCount += 1;
    00265     }
    00266
    00267     //
    00268     // Initialize the ideal processor number for the thread.
    00269     //
    00270     //  N.B. This must be done under the dispatcher lock to prevent byte
    00271     //      granularity problems on Alpha.
    00272     //
    00273
    00274     Process->ThreadSeed += 1;
    00275     Thread->IdealProcessor = (UCHAR)(Process->ThreadSeed % KeNumberProcessors);
    00276     KiUnlockDispatcherDatabase(OldIrql);
    00277     return;
    00278 }

NTKERNELAPI VOID KeInitializeTimer | ( | IN PKTIMER | Timer | ) |

Definition at line 43 of file timerobj.c.

References KeInitializeTimerEx().

Referenced by CcInitializeCacheManager(), CmpWorker(), ExpWorkerThreadBalanceManager(), IopErrorLogQueueRequest(), KdInitSystem(), KeBalanceSetManager(), KeInitializeThread(), MiInitializeSpecialPoolCriteria(), RawInputThread(), and VdmpDelayInterrupt().

    00049                    :
    00050
    00051     This function initializes a kernel timer object.
    00052
    00053 Arguments:
    00054
    00055     Timer - Supplies a pointer to a dispatcher object of type timer.
    00056
    00057 Return Value:
    00058
    00059     None.
    00060
    00061 --*/
    00062
    00063 {
    00064
    00065     //
    00066     // Initialize extended timer object with a type of notification and a
    00067     // period of zero.
    00068     //
    00069
    00070     KeInitializeTimerEx(Timer, NotificationTimer);
    00071     return;
    00072 }

NTKERNELAPI VOID KeInitializeTimerEx | ( | IN PKTIMER | Timer,
|  | IN TIMER_TYPE | Type
| ) |

Definition at line 75 of file timerobj.c.

References FALSE, NULL, and TimerNotificationObject.

Referenced by IoInitSystem(), IovpInternalDeferredCompletion(), KeInitializeTimer(), MmInitSystem(), NtCreateTimer(), RawInputThread(), and VerifierKeInitializeTimerEx().

    00082                    :
    00083
    00084     This function initializes an extended kernel timer object.
    00085
    00086 Arguments:
    00087
    00088     Timer - Supplies a pointer to a dispatcher object of type timer.
    00089
    00090     Type - Supplies the type of timer object; NotificationTimer or
    00091         SynchronizationTimer;
    00092
    00093 Return Value:
    00094
    00095     None.
    00096
    00097 --*/
    00098
    00099 {
    00100     //
    00101     // Initialize standard dispatcher object header and set initial
    00102     // state of timer.
    00103     //
    00104
    00105     Timer->Header.Type = TimerNotificationObject + Type;
    00106     Timer->Header.Inserted = FALSE;
    00107     Timer->Header.Size = sizeof(KTIMER) / sizeof(LONG);
    00108     Timer->Header.SignalState = FALSE;
    00109
    00110 #if DBG
    00111
    00112     Timer->TimerListEntry.Flink = NULL;
    00113     Timer->TimerListEntry.Blink = NULL;
    00114
    00115 #endif
    00116
    00117     InitializeListHead(&Timer->Header.WaitListHead);
    00118     Timer->DueTime.QuadPart = 0;
    00119     Timer->Period = 0;
    00120     return;
    00121 }

BOOLEAN KeInitSystem | ( | VOID |  | ) |

Definition at line 41 of file kiinit.c.

References FALSE, Initialized, KiChannelInitialization(), KiInitMachineDependent(), and TRUE.

    00047                    :
    00048
    00049     This function initializes executive structures implemented by the
    00050     kernel.
    00051
    00052     N.B. This function is only called during phase 1 initialization.
    00053
    00054 Arguments:
    00055
    00056     None.
    00057
    00058 Return Value:
    00059
    00060     A value of TRUE is returned if initialization is successful. Otherwise,
    00061     a value of FALSE is returned.
    00062
    00063 --*/
    00064
    00065 {
    00066
    00067     BOOLEAN Initialized = TRUE;
    00068
    00069     //
    00070     // Initialize the executive objects.
    00071     //
    00072
    00073 #if 0
    00074
    00075     if ((Initialized = KiChannelInitialization()) == FALSE) {
    00076         KdPrint(("Kernel: Channel initialization failed\n"));
    00077     }
    00078
    00079 #endif
    00080
    00081 #if defined(i386)
    00082
    00083     //
    00084     // Perform platform dependent initialization.
    00085     //
    00086
    00087     Initialized = KiInitMachineDependent();
    00088
    00089 #endif
    00090
    00091
    00092     return Initialized;
    00093 }

NTKERNELAPI BOOLEAN KeInsertByKeyDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue,
|  | IN PKDEVICE_QUEUE_ENTRY | DeviceQueueEntry,
|  | IN ULONG | SortKey
| ) |

Definition at line 145 of file devquobj.c.

References ASSERT, ASSERT_DEVICE_QUEUE, DISPATCH_LEVEL, FALSE, KDEVICE_QUEUE_ENTRY, _KDEVICE_QUEUE_ENTRY::SortKey, and TRUE.

Referenced by IoStartPacket().

    00153                    :
    00154
    00155     This function inserts a device queue entry into the specified device
    00156     queue according to a sort key. If the device is not busy, then it is
    00157     set busy and the entry is not placed in the device queue. Otherwise
    00158     the specified entry is placed in the device queue at a position such
    00159     that the specified sort key is greater than or equal to its predecessor
    00160     and less than its successor.
    00161
    00162     N.B. This function can only be called from DISPATCH_LEVEL.
    00163
    00164 Arguments:
    00165
    00166     DeviceQueue - Supplies a pointer to a control object of type device queue.
    00167
    00168     DeviceQueueEntry - Supplies a pointer to a device queue entry.
    00169
    00170     SortKey - Supplies the sort key by which the position to insert the device
    00171         queue entry is to be determined.
    00172
    00173 Return Value:
    00174
    00175     If the device is not busy, then a value of FALSE is returned. Otherwise a
    00176     value of TRUE is returned.
    00177
    00178 --*/
    00179
    00180 {
    00181
    00182     BOOLEAN Inserted;
    00183     PLIST_ENTRY NextEntry;
    00184     PKDEVICE_QUEUE_ENTRY QueueEntry;
    00185
    00186     ASSERT_DEVICE_QUEUE(DeviceQueue);
    00187     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    00188
    00189     //
    00190     // Lock specified device queue.
    00191     //
    00192
    00193     KiAcquireSpinLock(&DeviceQueue->Lock);
    00194
    00195     //
    00196     // Insert the specified device queue entry in the device queue at the
    00197     // position specified by the sort key if the device queue is busy.
    00198     // Otherwise set the device queue busy an don't insert the device queue
    00199     // entry.
    00200     //
    00201
    00202     DeviceQueueEntry->SortKey = SortKey;
    00203     if (DeviceQueue->Busy == TRUE) {
    00204         Inserted = TRUE;
    00205         NextEntry = DeviceQueue->DeviceListHead.Flink;
    00206         while (NextEntry != &DeviceQueue->DeviceListHead) {
    00207             QueueEntry = CONTAINING_RECORD(NextEntry, KDEVICE_QUEUE_ENTRY,
    00208                                            DeviceListEntry);
    00209             if (SortKey < QueueEntry->SortKey) {
    00210                 break;
    00211             }
    00212             NextEntry = NextEntry->Flink;
    00213         }
    00214         NextEntry = NextEntry->Blink;
    00215         InsertHeadList(NextEntry, &DeviceQueueEntry->DeviceListEntry);
    00216     } else {
    00217         DeviceQueue->Busy = TRUE;
    00218         Inserted = FALSE;
    00219     }
    00220     DeviceQueueEntry->Inserted = Inserted;
    00221     KiReleaseSpinLock(&DeviceQueue->Lock);
    00222     return Inserted;
    00223 }

NTKERNELAPI BOOLEAN KeInsertDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue,
|  | IN PKDEVICE_QUEUE_ENTRY | DeviceQueueEntry
| ) |

Definition at line 83 of file devquobj.c.

References ASSERT, ASSERT_DEVICE_QUEUE, DISPATCH_LEVEL, FALSE, PKDEVICE_QUEUE_ENTRY, and TRUE.

Referenced by IoAllocateController(), and IoStartPacket().

    00090                    :
    00091
    00092     This function inserts a device queue entry at the tail of the specified
    00093     device queue. If the device is not busy, then it is set busy and the entry
    00094     is not placed in the device queue. Otherwise the specified entry is placed
    00095     at the end of the device queue.
    00096
    00097     N.B. This function can only be called from DISPATCH_LEVEL.
    00098
    00099 Arguments:
    00100
    00101     DeviceQueue - Supplies a pointer to a control object of type device queue.
    00102
    00103     DeviceQueueEntry - Supplies a pointer to a device queue entry.
    00104
    00105 Return Value:
    00106
    00107     If the device is not busy, then a value of FALSE is returned. Otherwise a
    00108     value of TRUE is returned.
    00109
    00110 --*/
    00111
    00112 {
    00113
    00114     BOOLEAN Inserted;
    00115
    00116     ASSERT_DEVICE_QUEUE(DeviceQueue);
    00117     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    00118
    00119     //
    00120     // Lock specified device queue.
    00121     //
    00122
    00123     KiAcquireSpinLock(&DeviceQueue->Lock);
    00124
    00125     //
    00126     // Insert the specified device queue entry at the end of the device queue
    00127     // if the device queue is busy. Otherwise set the device queue busy and
    00128     // don't insert the device queue entry.
    00129     //
    00130
    00131     if (DeviceQueue->Busy == TRUE) {
    00132         Inserted = TRUE;
    00133         InsertTailList(&DeviceQueue->DeviceListHead,
    00134                        &DeviceQueueEntry->DeviceListEntry);
    00135     } else {
    00136         DeviceQueue->Busy = TRUE;
    00137         Inserted = FALSE;
    00138     }
    00139     DeviceQueueEntry->Inserted = Inserted;
    00140     KiReleaseSpinLock(&DeviceQueue->Lock);
    00141     return Inserted;
    00142 }

NTKERNELAPI LONG KeInsertHeadQueue | ( | IN PRKQUEUE | Queue,
|  | IN PLIST_ENTRY | Entry
| ) |

Definition at line 181 of file queueobj.c.

References ASSERT, ASSERT_QUEUE, DISPATCH_LEVEL, KiInsertQueue(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and TRUE.

    00188                    :
    00189
    00190     This function inserts the specified entry in the queue object entry
    00191     list and attempts to satisfy the wait of a single waiter.
    00192
    00193     N.B. The wait discipline for Queue object is LIFO.
    00194
    00195 Arguments:
    00196
    00197     Queue - Supplies a pointer to a dispatcher object of type Queue.
    00198
    00199     Entry - Supplies a pointer to a list entry that is inserted in the
    00200         queue object entry list.
    00201
    00202 Return Value:
    00203
    00204     The previous signal state of the Queue object.
    00205
    00206 --*/
    00207
    00208 {
    00209
    00210     KIRQL OldIrql;
    00211     LONG OldState;
    00212
    00213     ASSERT_QUEUE(Queue);
    00214     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00215
    00216     //
    00217     // Raise IRQL to dispatcher level and lock dispatcher database.
    00218     //
    00219
    00220     KiLockDispatcherDatabase(&OldIrql);
    00221
    00222     //
    00223     // Insert the specified entry in the queue object entry list.
    00224     //
    00225
    00226     OldState = KiInsertQueue(Queue, Entry, TRUE);
    00227
    00228     //
    00229     // Unlock the dispather database, lower IRQL to the previous level, and
    00230     // return signal state of Queue object.
    00231     //
    00232
    00233     KiUnlockDispatcherDatabase(OldIrql);
    00234     return OldState;
    00235 }

NTKERNELAPI LONG KeInsertQueue | ( | IN PRKQUEUE | Queue,
|  | IN PLIST_ENTRY | Entry
| ) |

Definition at line 124 of file queueobj.c.

References ASSERT, ASSERT_QUEUE, DISPATCH_LEVEL, FALSE, KiInsertQueue(), KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by ExQueueWorkItem(), FsRtlpPostStackOverflow(), IopCompleteRequest(), and IoSetIoCompletion().

    00131                    :
    00132
    00133     This function inserts the specified entry in the queue object entry
    00134     list and attempts to satisfy the wait of a single waiter.
    00135
    00136     N.B. The wait discipline for Queue object is LIFO.
    00137
    00138 Arguments:
    00139
    00140     Queue - Supplies a pointer to a dispatcher object of type Queue.
    00141
    00142     Entry - Supplies a pointer to a list entry that is inserted in the
    00143         queue object entry list.
    00144
    00145 Return Value:
    00146
    00147     The previous signal state of the Queue object.
    00148
    00149 --*/
    00150
    00151 {
    00152
    00153     KIRQL OldIrql;
    00154     LONG OldState;
    00155
    00156     ASSERT_QUEUE(Queue);
    00157     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00158
    00159     //
    00160     // Raise IRQL to dispatcher level and lock dispatcher database.
    00161     //
    00162
    00163     KiLockDispatcherDatabase(&OldIrql);
    00164
    00165     //
    00166     // Insert the specified entry in the queue object entry list.
    00167     //
    00168
    00169     OldState = KiInsertQueue(Queue, Entry, FALSE);
    00170
    00171     //
    00172     // Unlock the dispather database, lower IRQL to the previous level, and
    00173     // return signal state of Queue object.
    00174     //
    00175
    00176     KiUnlockDispatcherDatabase(OldIrql);
    00177     return OldState;
    00178 }

NTKERNELAPI BOOLEAN KeInsertQueueApc | ( | IN PRKAPC | Apc,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2,
|  | IN KPRIORITY | Increment
| ) |

Definition at line 217 of file apcobj.c.

References _KTHREAD::ApcQueueable, ASSERT, ASSERT_APC, DISPATCH_LEVEL, FALSE, Increment, KiInsertQueueApc(), KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by CmpPostNotify(), ExpTimerDpcRoutine(), IopCompleteRequest(), IoRaiseHardError(), IoRaiseInformationalHardError(), KeSetAutoAlignmentThread(), NtGetContextThread(), NtQueueApcThread(), NtSetContextThread(), PspExitNormalApc(), PspTerminateThreadByPointer(), and PspUserThreadStartup().

    00226                    :
    00227
    00228     This function inserts an APC object into the APC queue specifed by the
    00229     thread and processor mode fields of the APC object. If the APC object
    00230     is already in an APC queue or APC queuing is disabled, then no operation
    00231     is performed. Otherwise the APC object is inserted in the specified queue
    00232     and appropriate scheduling decisions are made.
    00233
    00234 Arguments:
    00235
    00236     Apc - Supplies a pointer to a control object of type APC.
    00237
    00238     SystemArgument1, SystemArgument2 - Supply a set of two arguments that
    00239         contain untyped data provided by the executive.
    00240
    00241     Increment - Supplies the priority increment that is to be applied if
    00242         queuing the APC causes a thread wait to be satisfied.
    00243
    00244 Return Value:
    00245
    00246     If the APC object is already in an APC queue or APC queuing is disabled,
    00247     then a value of FALSE is returned. Otherwise a value of TRUE is returned.
    00248
    00249 --*/
    00250
    00251 {
    00252
    00253     BOOLEAN Inserted;
    00254     KIRQL OldIrql;
    00255     PRKTHREAD Thread;
    00256
    00257     ASSERT_APC(Apc);
    00258     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00259
    00260     //
    00261     // Raise IRQL to dispatcher level and lock dispatcher database.
    00262     //
    00263
    00264     KiLockDispatcherDatabase(&OldIrql);
    00265
    00266     //
    00267     // If APC queuing is disabled, then set inserted to FALSE. Else save
    00268     // system parameter values in APC object, and attempt to queue APC.
    00269     //
    00270
    00271     Thread = Apc->Thread;
    00272     if (Thread->ApcQueueable == FALSE) {
    00273         Inserted = FALSE;
    00274
    00275     } else {
    00276         Apc->SystemArgument1 = SystemArgument1;
    00277         Apc->SystemArgument2 = SystemArgument2;
    00278         Inserted = KiInsertQueueApc(Apc, Increment);
    00279     }
    00280
    00281     //
    00282     // Unlock the dispatcher database, lower IRQL to its previous value,
    00283     // and return whether APC object was inserted in APC queue.
    00284     //
    00285
    00286     KiUnlockDispatcherDatabase(OldIrql);
    00287     return Inserted;
    00288 }

NTKERNELAPI BOOLEAN KeInsertQueueDpc | ( | IN PRKDPC | Dpc,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 89 of file dpcobj.c.

References ASSERT_DPC, DISPATCH_LEVEL, FALSE, HIGH_LEVEL, HighImportance, Index, IPI_DPC, KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiIpiSend(), KiProcessorBlock, KiRequestSoftwareInterrupt(), Lock, LowImportance, MAXIMUM_PROCESSORS, NULL, and TRUE.

Referenced by KdExitDebugger(), KeSetTimerEx(), KiCalibrateTimeAdjustment(), and KiTimerListExpire().

    00097                    :
    00098
    00099     This function inserts a DPC object into the DPC queue. If the DPC object
    00100     is already in the DPC queue, then no operation is performed. Otherwise,
    00101     the DPC object is inserted in the DPC queue and a dispatch interrupt is
    00102     requested.
    00103
    00104 Arguments:
    00105
    00106     Dpc - Supplies a pointer to a control object of type DPC.
    00107
    00108     SystemArgument1, SystemArgument2  - Supply a set of two arguments that
    00109         contain untyped data provided by the executive.
    00110
    00111 Return Value:
    00112
    00113     If the DPC object is already in a DPC queue, then a value of FALSE is
    00114     returned. Otherwise a value of TRUE is returned.
    00115
    00116 --*/
    00117
    00118 {
    00119
    00120     ULONG Index;
    00121     PKSPIN_LOCK Lock;
    00122     KIRQL OldIrql;
    00123     PKPRCB Prcb;
    00124     ULONG Processor;
    00125
    00126     ASSERT_DPC(Dpc);
    00127
    00128     //
    00129     // Disable interrupts.
    00130     //
    00131
    00132     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    00133
    00134     //
    00135     // Acquire the DPC queue lock for the specified target processor.
    00136     //
    00137
    00138 #if !defined(NT_UP)
    00139
    00140     if (Dpc->Number >= MAXIMUM_PROCESSORS) {
    00141         Processor = Dpc->Number - MAXIMUM_PROCESSORS;
    00142         Prcb = KiProcessorBlock[Processor];
    00143
    00144     } else {
    00145         Prcb = KeGetCurrentPrcb();
    00146     }
    00147
    00148     KiAcquireSpinLock(&Prcb->DpcLock);
    00149
    00150 #else
    00151
    00152     Prcb = KeGetCurrentPrcb();
    00153
    00154 #endif
    00155
    00156     //
    00157     // If the DPC object is not in a DPC queue, then store the system
    00158     // arguments, insert the DPC object in the DPC queue, increment the
    00159     // number of DPCs queued to the target processor, increment the DPC
    00160     // queue depth, set the address of the DPC target DPC spinlock, and
    00161     // request a dispatch interrupt if appropriate.
    00162     //
    00163
    00164     if ((Lock = InterlockedCompareExchangePointer(&Dpc->Lock, &Prcb->DpcLock, NULL)) == NULL) {
    00165         Prcb->DpcCount += 1;
    00166         Prcb->DpcQueueDepth += 1;
    00167         Dpc->SystemArgument1 = SystemArgument1;
    00168         Dpc->SystemArgument2 = SystemArgument2;
    00169
    00170         //
    00171         // If the DPC is of high importance, then insert the DPC at the
    00172         // head of the DPC queue. Otherwise, insert the DPC at the end
    00173         // of the DPC queue.
    00174         //
    00175
    00176         if (Dpc->Importance == HighImportance) {
    00177             InsertHeadList(&Prcb->DpcListHead, &Dpc->DpcListEntry);
    00178
    00179         } else {
    00180             InsertTailList(&Prcb->DpcListHead, &Dpc->DpcListEntry);
    00181         }
    00182         //
    00183         // A memory barrier is required here to synchronize with retire DPC
    00184         // list, which clears DpcRoutineActive and DpcInterruptRequested
    00185         // without owning the dispatcher lock.
    00186         //
    00187
    00188 #if defined(_ALPHA_) && !defined(NT_UP)
    00189
    00190         __MB();
    00191
    00192 #endif
    00193
    00194         //
    00195         // If a DPC routine is not active on the target processor, then
    00196         // request a dispatch interrupt if appropriate.
    00197         //
    00198
    00199         if ((Prcb->DpcRoutineActive == FALSE) &&
    00200             (Prcb->DpcInterruptRequested == FALSE)) {
    00201
    00202             //
    00203             // Request a dispatch interrupt on the current processor if
    00204             // the DPC is not of low importance, the length of the DPC
    00205             // queue has exceeded the maximum threshold, or if the DPC
    00206             // request rate is below the minimum threshold.
    00207             //
    00208
    00209 #if defined(NT_UP)
    00210
    00211             if ((Dpc->Importance != LowImportance) ||
    00212                 (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
    00213                 (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
    00214                 Prcb->DpcInterruptRequested = TRUE;
    00215                 KiRequestSoftwareInterrupt(DISPATCH_LEVEL);
    00216             }
    00217
    00218             //
    00219             // If the DPC is being queued to another processor and the
    00220             // DPC is of high importance, or the length of the other
    00221             // processor's DPC queue has exceeded the maximum threshold,
    00222             // then request a dispatch interrupt.
    00223             //
    00224
    00225 #else
    00226
    00227             if (Prcb != KeGetCurrentPrcb()) {
    00228                 if (((Dpc->Importance == HighImportance) ||
    00229                      (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth))) {
    00230                     Prcb->DpcInterruptRequested = TRUE;
    00231                     KiIpiSend((KAFFINITY)(1 << Processor), IPI_DPC);
    00232                 }
    00233
    00234             } else {
    00235
    00236                 //
    00237                 // Request a dispatch interrupt on the current processor if
    00238                 // the DPC is not of low importance, the length of the DPC
    00239                 // queue has exceeded the maximum threshold, or if the DPC
    00240                 // request rate is below the minimum threshold.
    00241                 //
    00242
    00243                 if ((Dpc->Importance != LowImportance) ||
    00244                     (Prcb->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
    00245                     (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
    00246                     Prcb->DpcInterruptRequested = TRUE;
    00247                     KiRequestSoftwareInterrupt(DISPATCH_LEVEL);
    00248                 }
    00249             }
    00250
    00251 #endif
    00252
    00253         }
    00254      }
    00255
    00256      //
    00257      // Release the DPC lock, enable interrupts, and return whether the
    00258      // DPC was queued or not.
    00259      //
    00260
    00261 #if !defined(NT_UP)
    00262
    00263      KiReleaseSpinLock(&Prcb->DpcLock);
    00264
    00265 #endif
    00266
    00267      KeLowerIrql(OldIrql);
    00268      return (Lock == NULL);
    00269 }

BOOLEAN FASTCALL KeInvalidAccessAllowed | ( | IN PVOID TrapInformation | OPTIONAL | ) |

| Referenced by KiMemoryFault(), and MmAccessFault().

NTKERNELAPI LONG KePulseEvent | ( | IN PRKEVENT | Event,
|  | IN KPRIORITY | Increment,
|  | IN BOOLEAN | Wait
| ) |

Definition at line 167 of file eventobj.c.

References ASSERT, ASSERT_EVENT, DISPATCH_LEVEL, Event(), FALSE, Increment, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), _KTHREAD::WaitIrql, and _KTHREAD::WaitNext.

Referenced by ExUnlockHandleTableEntry(), MiFlushSectionInternal(), MiUnmapImageHeaderInHyperSpace(), MiWriteComplete(), MmLockPagableSectionByHandle(), MmUnlockPagableImageSection(), NtPulseEvent(), and xxxSwitchDesktop().

    00175                    :
    00176
    00177     This function atomically sets the signal state of an event object to
    00178     Signaled, attempts to satisfy as many Waits as possible, and then resets
    00179     the signal state of the event object to Not-Signaled. The previous signal
    00180     state of the event object is returned as the function value.
    00181
    00182 Arguments:
    00183
    00184     Event - Supplies a pointer to a dispatcher object of type event.
    00185
    00186     Increment - Supplies the priority increment that is to be applied
    00187        if setting the event causes a Wait to be satisfied.
    00188
    00189     Wait - Supplies a boolean value that signifies whether the call to
    00190        KePulseEvent will be immediately followed by a call to one of the
    00191        kernel Wait functions.
    00192
    00193 Return Value:
    00194
    00195     The previous signal state of the event object.
    00196
    00197 --*/
    00198
    00199 {
    00200
    00201     KIRQL OldIrql;
    00202     LONG OldState;
    00203     PRKTHREAD Thread;
    00204
    00205     ASSERT_EVENT(Event);
    00206     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00207
    00208     //
    00209     // Raise IRQL to dispatcher level and lock dispatcher database.
    00210     //
    00211
    00212     KiLockDispatcherDatabase(&OldIrql);
    00213
    00214     //
    00215     // If the current state of the event object is Not-Signaled and
    00216     // the wait queue is not empty, then set the state of the event
    00217     // to Signaled, satisfy as many Waits as possible, and then reset
    00218     // the state of the event to Not-Signaled.
    00219     //
    00220
    00221     OldState = Event->Header.SignalState;
    00222     if ((OldState == 0) && (IsListEmpty(&Event->Header.WaitListHead) == FALSE)) {
    00223         Event->Header.SignalState = 1;
    00224         KiWaitTest(Event, Increment);
    00225     }
    00226
    00227     Event->Header.SignalState = 0;
    00228
    00229     //
    00230     // If the value of the Wait argument is TRUE, then return to the
    00231     // caller with IRQL raised and the dispatcher database locked. Else
    00232     // release the dispatcher database lock and lower IRQL to the
    00233     // previous value.
    00234     //
    00235
    00236     if (Wait != FALSE) {
    00237         Thread = KeGetCurrentThread();
    00238         Thread->WaitIrql = OldIrql;
    00239         Thread->WaitNext = Wait;
    00240
    00241     } else {
    00242        KiUnlockDispatcherDatabase(OldIrql);
    00243     }
    00244
    00245     //
    00246     // Return previous signal state of event object.
    00247     //
    00248
    00249     return OldState;
    00250 }

NTKERNELAPI KAFFINITY KeQueryActiveProcessors | ( | VOID |  | ) |

Definition at line 1004 of file ke/miscc.c.

References KeActiveProcessors, and PAGED_CODE.

    01009                    :
    01010
    01011     This function returns the current set of active processors
    01012     in the system.
    01013
    01014 Arguments:
    01015
    01016     None.
    01017
    01018 Return Value:
    01019
    01020     KAFFINITY bitmask representing the set of active processors
    01021
    01022 --*/
    01023
    01024 {
    01025     PAGED_CODE();
    01026
    01027     return(KeActiveProcessors);
    01028 }
    }

BOOLEAN KeQueryAutoAlignmentThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 869 of file thredobj.c.

References ASSERT_THREAD.

    00875                    :
    00876
    00877     This function returns the data alignment handling mode for the specified
    00878     thread.
    00879
    00880 Arguments:
    00881
    00882     None.
    00883
    00884 Return Value:
    00885
    00886     A value of TRUE is returned if data alignment exceptions are being
    00887     automatically handled by the kernel. Otherwise, a value of FALSE
    00888     is returned.
    00889
    00890 --*/
    00891
    00892 {
    00893
    00894     ASSERT_THREAD(Thread);
    00895
    00896     //
    00897     // Return the data alignment handling mode for the thread.
    00898     //
    00899
    00900     return Thread->AutoAlignment;
    00901 }

LONG KeQueryBasePriorityThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 904 of file thredobj.c.

References ASSERT, ASSERT_THREAD, _KPROCESS::BasePriority, DISPATCH_LEVEL, Increment, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtQueryInformationThread().

    00910                    :
    00911
    00912     This function returns the base priority increment of the specified
    00913     thread.
    00914
    00915 Arguments:
    00916
    00917     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00918
    00919 Return Value:
    00920
    00921     The base priority increment of the specified thread.
    00922
    00923 --*/
    00924
    00925 {
    00926
    00927     LONG Increment;
    00928     KIRQL OldIrql;
    00929     PKPROCESS Process;
    00930
    00931     ASSERT_THREAD(Thread);
    00932     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00933
    00934     //
    00935     // Raise IRQL to dispatcher level and lock dispatcher database.
    00936     //
    00937
    00938     KiLockDispatcherDatabase(&OldIrql);
    00939
    00940     //
    00941     // If priority saturation occured the last time the thread base priority
    00942     // was set, then return the saturation increment value. Otherwise, compute
    00943     // the increment value as the difference between the thread base priority
    00944     // and the process base priority.
    00945     //
    00946
    00947     Process = Thread->ApcStatePointer[0]->Process;
    00948     Increment = Thread->BasePriority - Process->BasePriority;
    00949     if (Thread->Saturation != 0) {
    00950         Increment = ((HIGH_PRIORITY + 1) / 2) * Thread->Saturation;
    00951     }
    00952
    00953     //
    00954     // Unlock dispatcher database and lower IRQL to its previous
    00955     // value.
    00956     //
    00957
    00958     KiUnlockDispatcherDatabase(OldIrql);
    00959
    00960     //
    00961     // Return the previous thread base priority increment.
    00962     //
    00963
    00964     return Increment;
    00965 }

NTKERNELAPI ULONGLONG KeQueryInterruptTime | ( | VOID |  | ) |

Definition at line 122 of file ke/miscc.c.

Referenced by ExGetNextWakeTime(), and KiCalibrateTimeAdjustment().

    00128                    :
    00129
    00130     This function returns the current interrupt time by determining when the
    00131     time is stable and then returning its value.
    00132
    00133 Arguments:
    00134
    00135     CurrentTime - Supplies a pointer to a variable that will receive the
    00136         current system time.
    00137
    00138 Return Value:
    00139
    00140     None.
    00141
    00142 --*/
    00143
    00144 {
    00145
    00146     LARGE_INTEGER CurrentTime;
    00147
    00148     KiQueryInterruptTime(&CurrentTime);
    00149     return CurrentTime.QuadPart;
    00150 }

ULONG KeQueryIntervalProfile | ( | IN KPROFILE_SOURCE | Source | ) |

Definition at line 163 of file profobj.c.

References HAL_PROFILE_SOURCE_INFORMATION, HalProfileSourceInformation, HalQuerySystemInformation, _HAL_PROFILE_SOURCE_INFORMATION::Interval, KiProfileAlignmentFixupInterval, KiProfileInterval, NT_SUCCESS, NTSTATUS(), _HAL_PROFILE_SOURCE_INFORMATION::Source, Status, and _HAL_PROFILE_SOURCE_INFORMATION::Supported.

Referenced by NtQueryIntervalProfile().

    00169                    :
    00170
    00171     This function returns the profile sample interval the system is
    00172     currently using.
    00173
    00174 Arguments:
    00175
    00176     ProfileSource - Supplies the profile source to be queried.
    00177
    00178 Return Value:
    00179
    00180     Sample interval in units of 100ns.
    00181
    00182 --*/
    00183
    00184 {
    00185
    00186     HAL_PROFILE_SOURCE_INFORMATION ProfileSourceInfo;
    00187     ULONG ReturnedLength;
    00188     NTSTATUS Status;
    00189
    00190     if (ProfileSource == ProfileTime) {
    00191
    00192         //
    00193         // Return the current sampling interval in 100ns units.
    00194         //
    00195
    00196         return KiProfileInterval;
    00197
    00198     } else if (ProfileSource == ProfileAlignmentFixup) {
    00199         return KiProfileAlignmentFixupInterval;
    00200
    00201     } else {
    00202
    00203         //
    00204         // The HAL is responsible for tracking this profile interval.
    00205         //
    00206
    00207         ProfileSourceInfo.Source = ProfileSource;
    00208         Status = HalQuerySystemInformation(HalProfileSourceInformation,
    00209                                            sizeof(HAL_PROFILE_SOURCE_INFORMATION),
    00210                                            &ProfileSourceInfo,
    00211                                            &ReturnedLength);
    00212
    00213         if (NT_SUCCESS(Status) && ProfileSourceInfo.Supported) {
    00214             return ProfileSourceInfo.Interval;
    00215
    00216         } else {
    00217             return 0;
    00218         }
    00219     }
    00220 }

NTKERNELAPI KPRIORITY KeQueryPriorityThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 968 of file thredobj.c.

    00974                    :
    00975
    00976     This function returns the current priority of the specified thread.
    00977
    00978 Arguments:
    00979
    00980     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00981
    00982 Return Value:
    00983
    00984     The current priority of the specified thread.
    00985
    00986 --*/
    00987
    00988 {
    00989     return Thread->Priority;
    00990 }

NTKERNELAPI VOID KeQuerySystemTime | ( | OUT PLARGE_INTEGER | CurrentTime | ) |

Definition at line 242 of file cmwraper.c.

Referenced by CheckAppStarting(), CmDeleteValueKey(), CmpCreateLinkNode(), CmpCreateRootNode(), CmpDoCreateChild(), CmpSetSecurityDescriptorInfo(), CmSetValueKey(), DbgkExitProcess(), EhCreateChild(), ExDebugLogEvent(), ExGetNextWakeTime(), ExpAllocateUuids(), ExpRaiseHardError(), ExpUuidInitialization(), FsRtlAddToTunnelCache(), FsRtlPruneTunnelCache(), HvpWriteLog(), IoepFireWMIEvent(), IopAssign(), IopInitializeBuiltinDriver(), IopLoadDriver(), IovpCallDriver1(), IoWriteErrorLogEntry(), LfsInitializeLogFile(), LfsInitializeLogFileService(), LfsRestartLogFile(), MiDoReplacement(), MiInitializeSpecialPoolCriteria(), MiRearrangeWorkingSetExpansionList(), MiRememberUnloadedDriver(), MiSessionOutSwapProcess(), MmInitializeProcessAddressSpace(), MmWorkingSetManager(), NtCreateSymbolicLinkObject(), NtQuerySystemInformation(), NtTerminateProcess(), PspCreateProcess(), PspCreateThread(), PspExitThread(), and ViInjectResourceFailure().

    00245 {
    00246     NtQuerySystemTime(SystemTime);
    00247 }

NTKERNELAPI ULONG KeQueryTimeIncrement | ( | VOID |  | ) |

Definition at line 211 of file ke/miscc.c.

References KeMaximumIncrement.

Referenced by CcInitializeCacheManager().

    00217                    :
    00218
    00219     This function returns the time increment value in 100ns units. This
    00220     is the value that is added to the system time at each interval clock
    00221     interrupt.
    00222
    00223 Arguments:
    00224
    00225     None.
    00226
    00227 Return Value:
    00228
    00229     The time increment value is returned as the function value.
    00230
    00231 --*/
    00232
    00233 {
    00234
    00235     return KeMaximumIncrement;
    00236 }

ULONGLONG KeQueryTimerDueTime | ( | IN PKTIMER | Timer | ) |

Definition at line 410 of file timerobj.c.

References ASSERT_TIMER, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by ExGetNextWakeTime().

    00416                    :
    00417
    00418     This function returns the InterruptTime at which the timer is
    00419     pending.   0 is returned if the timer is not pending.
    00420
    00421     N.B. This function may only be called by the system sleep code.
    00422
    00423 Arguments:
    00424
    00425     Timer - Supplies a pointer to a dispatcher object of type timer.
    00426
    00427 Return Value:
    00428
    00429     Returns the amount of time remaining on the timer, or 0 if the
    00430     timer is not pending.
    00431
    00432 --*/
    00433
    00434 {
    00435
    00436     KIRQL OldIrql;
    00437     LARGE_INTEGER InterruptTime;
    00438     ULONGLONG DueTime;
    00439
    00440     ASSERT_TIMER(Timer);
    00441
    00442     //
    00443     // Raise IRQL to dispatcher level and lock dispatcher database.
    00444     //
    00445
    00446     KiLockDispatcherDatabase(&OldIrql);
    00447
    00448     //
    00449     // If the timer is currently pending, compute its due time
    00450     //
    00451
    00452     DueTime = 0;
    00453     if (Timer->Header.Inserted) {
    00454         DueTime = Timer->DueTime.QuadPart;
    00455     }
    00456
    00457     //
    00458     // Unlock the dispatcher database and lower IRQL to its previous
    00459     // value, and return the due time
    00460     //
    00461
    00462     KiUnlockDispatcherDatabase(OldIrql);
    00463     return DueTime;
    00464 }

NTSTATUS KeRaiseUserException | ( | IN NTSTATUS | ExceptionCode | ) |

Definition at line 1024 of file alpha/exceptn.c.

References ASSERT, KeGetCurrentThread, KeRaiseUserExceptionDispatcher, and UserMode.

Referenced by NtClose(), and NtSetEvent().

    01030                    :
    01031
    01032     This function causes an exception to be raised in the calling thread's user-mode
    01033     context. It does this by editing the trap frame the kernel was entered with to
    01034     point to trampoline code that raises the requested exception.
    01035
    01036 Arguments:
    01037
    01038     ExceptionCode - Supplies the status value to be used as the exception
    01039         code for the exception that is to be raised.
    01040
    01041 Return Value:
    01042
    01043     The status value that should be returned by the caller.
    01044
    01045 --*/
    01046
    01047 {
    01048
    01049     PKTRAP_FRAME TrapFrame;
    01050
    01051     ASSERT(KeGetPreviousMode() == UserMode);
    01052
    01053     TrapFrame = KeGetCurrentThread()->TrapFrame;
    01054
    01055     TrapFrame->Fir = (ULONGLONG)(LONG_PTR)KeRaiseUserExceptionDispatcher;
    01056     return(ExceptionCode);
    01057 }

NTKERNELAPI LONG KeReadStateEvent | ( | IN PRKEVENT | Event | ) |

Definition at line 253 of file eventobj.c.

References ASSERT_EVENT, and Event().

Referenced by IopCancelAlertedRequest(), IopConnectLinkTrackingPort(), IopSendMessageToTrackService(), NtQueryEvent(), and PspAddProcessToJob().

    00259                    :
    00260
    00261     This function reads the current signal state of an event object.
    00262
    00263 Arguments:
    00264
    00265     Event - Supplies a pointer to a dispatcher object of type event.
    00266
    00267 Return Value:
    00268
    00269     The current signal state of the event object.
    00270
    00271 --*/
    00272
    00273 {
    00274
    00275     ASSERT_EVENT(Event);
    00276
    00277     //
    00278     // Return current signal state of event object.
    00279     //
    00280
    00281     return Event->Header.SignalState;
    00282 }

LONG KeReadStateMutant | ( | IN | PRKMUTANT | ) |

Definition at line 146 of file mutntobj.c.

References ASSERT_MUTANT.

Referenced by NtQueryMutant().

    00152                    :
    00153
    00154     This function reads the current signal state of a mutant object.
    00155
    00156 Arguments:
    00157
    00158     Mutant - Supplies a pointer to a dispatcher object of type mutant.
    00159
    00160 Return Value:
    00161
    00162     The current signal state of the mutant object.
    00163
    00164 --*/
    00165
    00166 {
    00167
    00168     ASSERT_MUTANT(Mutant);
    00169
    00170     //
    00171     // Return current signal state of mutant object.
    00172     //
    00173
    00174     return Mutant->Header.SignalState;
    00175 }

LONG KeReadStateProcess | ( | IN PRKPROCESS | Process | ) |

Definition at line 624 of file procobj.c.

References ASSERT_PROCESS.

Referenced by NtSetInformationJobObject(), NtSetInformationProcess(), and PsLockProcess().

    00630                    :
    00631
    00632     This function reads the current signal state of a process object.
    00633
    00634 Arguments:
    00635
    00636     Process - Supplies a pointer to a dispatcher object of type process.
    00637
    00638 Return Value:
    00639
    00640     The current signal state of the process object.
    00641
    00642 --*/
    00643
    00644 {
    00645
    00646     ASSERT_PROCESS(Process);
    00647
    00648     //
    00649     // Return current signal state of process object.
    00650     //
    00651
    00652     return Process->Header.SignalState;
    00653 }

NTKERNELAPI LONG KeReadStateQueue | ( | IN PRKQUEUE | Queue | ) |

Definition at line 92 of file queueobj.c.

References ASSERT_QUEUE.

Referenced by ExpDetectWorkerThreadDeadlock(), and NtQueryIoCompletion().

    00098                    :
    00099
    00100     This function reads the current signal state of a Queue object.
    00101
    00102 Arguments:
    00103
    00104     Queue - Supplies a pointer to a dispatcher object of type Queue.
    00105
    00106 Return Value:
    00107
    00108     The current signal state of the Queue object.
    00109
    00110 --*/
    00111
    00112 {
    00113
    00114     ASSERT_QUEUE(Queue);
    00115
    00116     //
    00117     // Return current signal state of Queue object.
    00118     //
    00119
    00120     return Queue->Header.SignalState;
    00121 }

NTKERNELAPI LONG KeReadStateSemaphore | ( | IN PRKSEMAPHORE | Semaphore | ) |

Definition at line 85 of file semphobj.c.

References ASSERT_SEMAPHORE.

Referenced by IoRaiseInformationalHardError(), LpcpDestroyPortQueue(), LpcRequestWaitReplyPort(), NtQuerySemaphore(), NtReplyWaitReplyPort(), NtRequestWaitReplyPort(), and NtSecureConnectPort().

    00091                    :
    00092
    00093     This function reads the current signal state of a semaphore object.
    00094
    00095 Arguments:
    00096
    00097     Semaphore - Supplies a pointer to a dispatcher object of type
    00098         semaphore.
    00099
    00100 Return Value:
    00101
    00102     The current signal state of the semaphore object.
    00103
    00104 --*/
    00105
    00106 {
    00107
    00108     ASSERT_SEMAPHORE( Semaphore );
    00109
    00110     //
    00111     // Return current signal state of semaphore object.
    00112     //
    00113
    00114     return Semaphore->Header.SignalState;
    00115 }

BOOLEAN KeReadStateThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 993 of file thredobj.c.

References ASSERT_THREAD.

Referenced by NtQueryInformationThread().

    00999                    :
    01000
    01001     This function reads the current signal state of a thread object.
    01002
    01003 Arguments:
    01004
    01005     Thread - Supplies a pointer to a dispatcher object of type thread.
    01006
    01007 Return Value:
    01008
    01009     The current signal state of the thread object.
    01010
    01011 --*/
    01012
    01013 {
    01014
    01015     ASSERT_THREAD(Thread);
    01016
    01017     //
    01018     // Return current signal state of thread object.
    01019     //
    01020
    01021     return (BOOLEAN)Thread->Header.SignalState;
    01022 }

NTKERNELAPI BOOLEAN KeReadStateTimer | ( | PKTIMER | Timer | ) |

VOID KeReadyThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 1025 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiReadyThread(), and KiUnlockDispatcherDatabase().

Referenced by PspCreateThread().

    01031                    :
    01032
    01033     This function readies a thread for execution. If the thread's process
    01034     is currently not in the balance set, then the thread is inserted in the
    01035     thread's process' ready queue. Else if the thread is higher priority than
    01036     another thread that is currently running on a processor then the thread
    01037     is selected for execution on that processor. Else the thread is inserted
    01038     in the dispatcher ready queue selected by its priority.
    01039
    01040 Arguments:
    01041
    01042     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01043
    01044 Return Value:
    01045
    01046     None.
    01047
    01048 --*/
    01049
    01050 {
    01051
    01052     KIRQL OldIrql;
    01053
    01054     ASSERT_THREAD(Thread);
    01055     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01056
    01057     //
    01058     // Raise IRQL to dispatcher level and lock dispatcher database.
    01059     //
    01060
    01061     KiLockDispatcherDatabase(&OldIrql);
    01062
    01063     //
    01064     // Ready the specified thread for execution.
    01065     //
    01066
    01067     KiReadyThread(Thread);
    01068
    01069     //
    01070     // Unlock dispatcher database and lower IRQL to its previous
    01071     // value.
    01072     //
    01073
    01074     KiUnlockDispatcherDatabase(OldIrql);
    01075     return;
    01076 }

NTKERNELAPI BOOLEAN KeRegisterBugCheckCallback | ( | IN PKBUGCHECK_CALLBACK_RECORD | CallbackRecord,
|  | IN PKBUGCHECK_CALLBACK_ROUTINE | CallbackRoutine,
|  | IN PVOID | Buffer,
|  | IN ULONG | Length,
|  | IN PUCHAR | Component
| ) |

Definition at line 1123 of file bugcheck.c.

References Buffer, BufferEmpty, BufferInserted, FALSE, HIGH_LEVEL, KeBugCheckCallbackListHead, KeBugCheckCallbackLock, KeLowerIrql(), KeRaiseIrql(), PKBUGCHECK_CALLBACK_ROUTINE, and TRUE.

    01133                    :
    01134
    01135     This function registers a bug check callback record. If the system
    01136     crashes, then the specified function will be called during bug check
    01137     processing so it may dump additional state in the specified bug check
    01138     buffer.
    01139
    01140     N.B. Bug check callback routines are called in reverse order of
    01141          registration, i.e., in LIFO order.
    01142
    01143 Arguments:
    01144
    01145     CallbackRecord - Supplies a pointer to a callback record.
    01146
    01147     CallbackRoutine - Supplies a pointer to the callback routine.
    01148
    01149     Buffer - Supplies a pointer to the bug check buffer.
    01150
    01151     Length - Supplies the length of the bug check buffer in bytes.
    01152
    01153     Component - Supplies a pointer to a zero terminated component
    01154         identifier.
    01155
    01156 Return Value:
    01157
    01158     If the specified bug check callback record is successfully registered,
    01159     then a value of TRUE is returned. Otherwise, a value of FALSE is returned.
    01160
    01161 --*/
    01162
    01163 {
    01164
    01165     BOOLEAN Inserted;
    01166     KIRQL OldIrql;
    01167
    01168     //
    01169     // Raise IRQL to HIGH_LEVEL and acquire the bug check callback list
    01170     // spinlock.
    01171     //
    01172
    01173     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    01174     KiAcquireSpinLock(&KeBugCheckCallbackLock);
    01175
    01176     //
    01177     // If the specified callback record is currently not registered, then
    01178     // register the callback record.
    01179     //
    01180
    01181     Inserted = FALSE;
    01182     if (CallbackRecord->State == BufferEmpty) {
    01183         CallbackRecord->CallbackRoutine = CallbackRoutine;
    01184         CallbackRecord->Buffer = Buffer;
    01185         CallbackRecord->Length = Length;
    01186         CallbackRecord->Component = Component;
    01187         CallbackRecord->Checksum =
    01188             ((ULONG_PTR)CallbackRoutine + (ULONG_PTR)Buffer + Length + (ULONG_PTR)Component);
    01189
    01190         CallbackRecord->State = BufferInserted;
    01191         InsertHeadList(&KeBugCheckCallbackListHead, &CallbackRecord->Entry);
    01192         Inserted = TRUE;
    01193     }
    01194
    01195     //
    01196     // Release the bug check callback spinlock, lower IRQL to its previous
    01197     // value, and return whether the callback record was successfully
    01198     // registered.
    01199     //
    01200
    01201     KiReleaseSpinLock(&KeBugCheckCallbackLock);
    01202     KeLowerIrql(OldIrql);
    01203     return Inserted;
    01204 }

NTKERNELAPI LONG KeReleaseMutant | ( | IN PRKMUTANT | Mutant,
|  | IN KPRIORITY | Increment,
|  | IN BOOLEAN | Abandoned,
|  | IN BOOLEAN | Wait
| ) |

Definition at line 178 of file mutntobj.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, ASSERT, ASSERT_MUTANT, DISPATCH_LEVEL, ExRaiseStatus(), FALSE, Increment, KeGetCurrentThread, _KTHREAD::KernelApcDisable, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiRequestSoftwareInterrupt(), KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, TRUE, _KTHREAD::WaitIrql, and _KTHREAD::WaitNext.

Referenced by ExpDeleteMutant(), KeReleaseMutex(), MiLoadSystemImage(), MiLookupPsLoadedModule(), MmAddVerifierThunks(), MmGetVerifierInformation(), MmSetVerifierInformation(), MmUnloadSystemImage(), NtDuplicateObject(), NtQueryInformationProcess(), NtReleaseMutant(), NtSignalAndWaitForSingleObject(), ObFindHandleForObject(), ObInitProcess(), and ObKillProcess().

    00187                    :
    00188
    00189     This function releases a mutant object by incrementing the mutant
    00190     count. If the resultant value is one, then an attempt is made to
    00191     satisfy as many Waits as possible. The previous signal state of
    00192     the mutant is returned as the function value. If the Abandoned
    00193     parameter is TRUE, then the mutant object is released by settings
    00194     the signal state to one.
    00195
    00196 Arguments:
    00197
    00198     Mutant - Supplies a pointer to a dispatcher object of type mutant.
    00199
    00200     Increment - Supplies the priority increment that is to be applied
    00201         if setting the event causes a Wait to be satisfied.
    00202
    00203     Abandoned - Supplies a boolean value that signifies whether the
    00204         mutant object is being abandoned.
    00205
    00206     Wait - Supplies a boolean value that signifies whether the call to
    00207         KeReleaseMutant will be immediately followed by a call to one
    00208         of the kernel Wait functions.
    00209
    00210 Return Value:
    00211
    00212     The previous signal state of the mutant object.
    00213
    00214 --*/
    00215
    00216 {
    00217
    00218     KIRQL OldIrql;
    00219     LONG OldState;
    00220     PRKTHREAD Thread;
    00221
    00222
    00223     ASSERT_MUTANT(Mutant);
    00224     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00225
    00226     //
    00227     // Raise IRQL to dispatcher level and lock dispatcher database.
    00228     //
    00229
    00230     KiLockDispatcherDatabase(&OldIrql);
    00231
    00232     //
    00233     // Capture the current signal state of the mutant object.
    00234     //
    00235
    00236     OldState = Mutant->Header.SignalState;
    00237
    00238     //
    00239     // If the Abandoned parameter is TRUE, then force the release of the
    00240     // mutant object by setting its ownership count to one and setting its
    00241     // abandoned state to TRUE. Otherwise increment mutant ownership count.
    00242     // If the result count is one, then remove the mutant object from the
    00243     // thread's owned mutant list, set the owner thread to NULL, and attempt
    00244     // to satisfy a Wait for the mutant object if the mutant object wait
    00245     // list is not empty.
    00246     //
    00247
    00248     Thread = KeGetCurrentThread();
    00249     if (Abandoned != FALSE) {
    00250         Mutant->Header.SignalState = 1;
    00251         Mutant->Abandoned = TRUE;
    00252
    00253     } else {
    00254
    00255         //
    00256         // If the Mutant object is not owned by the current thread, then
    00257         // unlock the dispatcher data base and raise an exception. Otherwise
    00258         // increment the ownership count.
    00259         //
    00260
    00261         if (Mutant->OwnerThread != Thread) {
    00262             KiUnlockDispatcherDatabase(OldIrql);
    00263             ExRaiseStatus(Mutant->Abandoned ?
    00264                           STATUS_ABANDONED : STATUS_MUTANT_NOT_OWNED);
    00265         }
    00266
    00267         Mutant->Header.SignalState += 1;
    00268     }
    00269
    00270     if (Mutant->Header.SignalState == 1) {
    00271         if (OldState <= 0) {
    00272             RemoveEntryList(&Mutant->MutantListEntry);
    00273             Thread->KernelApcDisable += Mutant->ApcDisable;
    00274             if ((Thread->KernelApcDisable == 0) &&
    00275                 (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE)) {
    00276                 Thread->ApcState.KernelApcPending = TRUE;
    00277                 KiRequestSoftwareInterrupt(APC_LEVEL);
    00278             }
    00279         }
    00280
    00281         Mutant->OwnerThread = (PKTHREAD)NULL;
    00282         if (IsListEmpty(&Mutant->Header.WaitListHead) == FALSE) {
    00283             KiWaitTest(Mutant, Increment);
    00284         }
    00285     }
    00286
    00287     //
    00288     // If the value of the Wait argument is TRUE, then return to
    00289     // caller with IRQL raised and the dispatcher database locked.
    00290     // Else release the dispatcher database lock and lower IRQL to
    00291     // its previous value.
    00292     //
    00293
    00294     if (Wait != FALSE) {
    00295         Thread->WaitNext = Wait;
    00296         Thread->WaitIrql = OldIrql;
    00297
    00298     } else {
    00299         KiUnlockDispatcherDatabase(OldIrql);
    00300     }
    00301
    00302     //
    00303     // Return previous signal state of mutant object.
    00304     //
    00305
    00306     return OldState;
    00307 }

NTKERNELAPI LONG KeReleaseMutex | ( | IN PRKMUTEX | Mutex,
|  | IN BOOLEAN | Wait
| ) |

NTKERNELAPI LONG KeReleaseSemaphore | ( | IN PRKSEMAPHORE | Semaphore,
|  | IN KPRIORITY | Increment,
|  | IN LONG | Adjustment,
|  | IN BOOLEAN | Wait
| ) |

Definition at line 118 of file semphobj.c.

References ASSERT, ASSERT_SEMAPHORE, DISPATCH_LEVEL, ExRaiseStatus(), FALSE, Increment, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), _KTHREAD::WaitIrql, and _KTHREAD::WaitNext.

Referenced by ExAllocatePool(), ExConvertExclusiveToSharedLite(), ExFreePool(), ExReleaseResourceForThreadLite(), ExReleaseResourceLite(), FsRtlDeregisterUncProvider(), FsRtlRegisterUncProvider(), IopAllocateBootResources(), IopAllocateResources(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopLegacyResourceAllocation(), IopQueryConflictList(), IopReallocateResources(), IopRebalance(), IoRaiseInformationalHardError(), LpcpDestroyPortQueue(), LpcRequestPort(), LpcRequestWaitReplyPort(), MiChargeCommitmentCantExpand(), MiCheckForControlAreaDeletion(), MiContractPagingFiles(), MiIssuePageExtendRequest(), MiIssuePageExtendRequestNoWait(), NtAcceptConnectPort(), NtCompleteConnectPort(), NtReleaseSemaphore(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestPort(), NtRequestWaitReplyPort(), NtSecureConnectPort(), NtSignalAndWaitForSingleObject(), Reader(), ReaderTurnedWriter(), SmbTraceCompleteRdr(), SmbTraceCompleteSrv(), and Writer().

    00127                    :
    00128
    00129     This function releases a semaphore by adding the specified adjustment
    00130     value to the current semaphore count and attempts to satisfy as many
    00131     Waits as possible. The previous signal state of the semaphore object
    00132     is returned as the function value.
    00133
    00134 Arguments:
    00135
    00136     Semaphore - Supplies a pointer to a dispatcher object of type
    00137         semaphore.
    00138
    00139     Increment - Supplies the priority increment that is to be applied
    00140         if releasing the semaphore causes a Wait to be satisfied.
    00141
    00142     Adjustment - Supplies value that is to be added to the current
    00143         semaphore count.
    00144
    00145     Wait - Supplies a boolean value that signifies whether the call to
    00146         KeReleaseSemaphore will be immediately followed by a call to one
    00147         of the kernel Wait functions.
    00148
    00149 Return Value:
    00150
    00151     The previous signal state of the semaphore object.
    00152
    00153 --*/
    00154
    00155 {
    00156
    00157     LONG NewState;
    00158     KIRQL OldIrql;
    00159     LONG OldState;
    00160     PRKTHREAD Thread;
    00161
    00162     ASSERT_SEMAPHORE( Semaphore );
    00163     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00164
    00165     //
    00166     // Raise IRQL to dispatcher level and lock dispatcher database.
    00167     //
    00168
    00169     KiLockDispatcherDatabase(&OldIrql);
    00170
    00171     //
    00172     // Capture the current signal state of the semaphore object and
    00173     // compute the new count value.
    00174     //
    00175
    00176     OldState = Semaphore->Header.SignalState;
    00177     NewState = OldState + Adjustment;
    00178
    00179     //
    00180     // If the new state value is greater than the limit or a carry occurs,
    00181     // then unlock the dispatcher database, and raise an exception.
    00182     //
    00183
    00184     if ((NewState > Semaphore->Limit) || (NewState < OldState)) {
    00185         KiUnlockDispatcherDatabase(OldIrql);
    00186         ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
    00187     }
    00188
    00189     //
    00190     // Set the new signal state of the semaphore object and set the wait
    00191     // next value. If the previous signal state was Not-Signaled (i.e.
    00192     // the count was zero), and the wait queue is not empty, then attempt
    00193     // to satisfy as many Waits as possible.
    00194     //
    00195
    00196     Semaphore->Header.SignalState = NewState;
    00197     if ((OldState == 0) && (IsListEmpty(&Semaphore->Header.WaitListHead) == FALSE)) {
    00198         KiWaitTest(Semaphore, Increment);
    00199     }
    00200
    00201     //
    00202     // If the value of the Wait argument is TRUE, then return to the
    00203     // caller with IRQL raised and the dispatcher database locked. Else
    00204     // release the dispatcher database lock and lower IRQL to its
    00205     // previous value.
    00206     //
    00207
    00208     if (Wait != FALSE) {
    00209         Thread = KeGetCurrentThread();
    00210         Thread->WaitNext = Wait;
    00211         Thread->WaitIrql = OldIrql;
    00212
    00213     } else {
    00214         KiUnlockDispatcherDatabase(OldIrql);
    00215     }
    00216
    00217     //
    00218     // Return previous signal state of sempahore object.
    00219     //
    00220
    00221     return OldState;
    00222 }
    }

NTKERNELAPI VOID KeReleaseSpinLock | ( | IN PKSPIN_LOCK | SpinLock,
|  | IN KIRQL | NewIrql
| ) |

NTKERNELAPI VOID KeReleaseSpinLockFromDpcLevel | ( | IN PKSPIN_LOCK | SpinLock | ) |

NTKERNELAPI PKDEVICE_QUEUE_ENTRY KeRemoveByKeyDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue,
|  | IN ULONG | SortKey
| ) |

Definition at line 294 of file devquobj.c.

References ASSERT, ASSERT_DEVICE_QUEUE, _KDEVICE_QUEUE_ENTRY::DeviceListEntry, DISPATCH_LEVEL, FALSE, _KDEVICE_QUEUE_ENTRY::Inserted, NULL, _KDEVICE_QUEUE_ENTRY::SortKey, and TRUE.

Referenced by IoStartNextPacketByKey().

    00301                    :
    00302
    00303     This function removes an entry from the specified device
    00304     queue. If the device queue is empty, then the device is set Not-Busy
    00305     and a NULL pointer is returned. Otherwise the an entry is removed
    00306     from the device queue and the address of device queue entry
    00307     is returned.  The queue is search for the first entry which has a value
    00308     greater than or equal to the SortKey.  If no such entry is found then the
    00309     first entry of the queue is returned.
    00310
    00311     N.B. This function can only be called from DISPATCH_LEVEL.
    00312
    00313 Arguments:
    00314
    00315     DeviceQueue - Supplies a pointer to a control object of type device queue.
    00316
    00317     SortKey - Supplies the sort key by which the position to remove the device
    00318         queue entry is to be determined.
    00319
    00320 Return Value:
    00321
    00322     A NULL pointer is returned if the device queue is empty. Otherwise a
    00323     pointer to a device queue entry is returned.
    00324
    00325 --*/
    00326
    00327 {
    00328
    00329     PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
    00330     PLIST_ENTRY NextEntry;
    00331
    00332     ASSERT_DEVICE_QUEUE(DeviceQueue);
    00333     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    00334
    00335     //
    00336     // Lock specified device queue.
    00337     //
    00338
    00339     KiAcquireSpinLock(&DeviceQueue->Lock);
    00340
    00341     ASSERT(DeviceQueue->Busy == TRUE);
    00342
    00343     //
    00344     // If the device queue is not empty, then remove the first entry from
    00345     // the queue. Otherwise set the device queue not busy.
    00346     //
    00347
    00348     if (IsListEmpty(&DeviceQueue->DeviceListHead) == TRUE) {
    00349         DeviceQueue->Busy = FALSE;
    00350         DeviceQueueEntry = (PKDEVICE_QUEUE_ENTRY)NULL;
    00351     } else {
    00352         NextEntry = DeviceQueue->DeviceListHead.Flink;
    00353         while (NextEntry != &DeviceQueue->DeviceListHead) {
    00354             DeviceQueueEntry = CONTAINING_RECORD(NextEntry, KDEVICE_QUEUE_ENTRY,
    00355                                            DeviceListEntry);
    00356             if (SortKey <= DeviceQueueEntry->SortKey) {
    00357                 break;
    00358             }
    00359             NextEntry = NextEntry->Flink;
    00360         }
    00361
    00362         if (NextEntry != &DeviceQueue->DeviceListHead) {
    00363             RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
    00364
    00365         } else {
    00366             NextEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
    00367             DeviceQueueEntry = CONTAINING_RECORD(NextEntry, KDEVICE_QUEUE_ENTRY,
    00368                                              DeviceListEntry);
    00369         }
    00370
    00371         DeviceQueueEntry->Inserted = FALSE;
    00372     }
    00373
    00374     //
    00375     // Release device queue spin lock and return address of device queue
    00376     // entry.
    00377     //
    00378
    00379     KiReleaseSpinLock(&DeviceQueue->Lock);
    00380     return DeviceQueueEntry;
    00381 }

NTKERNELAPI PKDEVICE_QUEUE_ENTRY KeRemoveDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue | ) |

Definition at line 226 of file devquobj.c.

References ASSERT, ASSERT_DEVICE_QUEUE, DISPATCH_LEVEL, FALSE, _KDEVICE_QUEUE_ENTRY::Inserted, NULL, and TRUE.

Referenced by IoFreeController(), and IoStartNextPacket().

    00232                    :
    00233
    00234     This function removes an entry from the head of the specified device
    00235     queue. If the device queue is empty, then the device is set Not-Busy
    00236     and a NULL pointer is returned. Otherwise the next entry is removed
    00237     from the head of the device queue and the address of device queue entry
    00238     is returned.
    00239
    00240     N.B. This function can only be called from DISPATCH_LEVEL.
    00241
    00242 Arguments:
    00243
    00244     DeviceQueue - Supplies a pointer to a control object of type device queue.
    00245
    00246 Return Value:
    00247
    00248     A NULL pointer is returned if the device queue is empty. Otherwise a
    00249     pointer to a device queue entry is returned.
    00250
    00251 --*/
    00252
    00253 {
    00254
    00255     PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
    00256     PLIST_ENTRY NextEntry;
    00257
    00258     ASSERT_DEVICE_QUEUE(DeviceQueue);
    00259     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
    00260
    00261     //
    00262     // Lock specified device queue.
    00263     //
    00264
    00265     KiAcquireSpinLock(&DeviceQueue->Lock);
    00266
    00267     ASSERT(DeviceQueue->Busy == TRUE);
    00268
    00269     //
    00270     // If the device queue is not empty, then remove the first entry from
    00271     // the queue. Otherwise set the device queue not busy.
    00272     //
    00273
    00274     if (IsListEmpty(&DeviceQueue->DeviceListHead) == TRUE) {
    00275         DeviceQueue->Busy = FALSE;
    00276         DeviceQueueEntry = (PKDEVICE_QUEUE_ENTRY)NULL;
    00277     } else {
    00278         NextEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
    00279         DeviceQueueEntry = CONTAINING_RECORD(NextEntry, KDEVICE_QUEUE_ENTRY,
    00280                                              DeviceListEntry);
    00281         DeviceQueueEntry->Inserted = FALSE;
    00282     }
    00283
    00284     //
    00285     // Release device queue spin lock and return address of device queue
    00286     // entry.
    00287     //
    00288
    00289     KiReleaseSpinLock(&DeviceQueue->Lock);
    00290     return DeviceQueueEntry;
    00291 }

NTKERNELAPI BOOLEAN KeRemoveEntryDeviceQueue | ( | IN PKDEVICE_QUEUE | DeviceQueue,
|  | IN PKDEVICE_QUEUE_ENTRY | DeviceQueueEntry
| ) |

Definition at line 384 of file devquobj.c.

References ASSERT, ASSERT_DEVICE_QUEUE, DISPATCH_LEVEL, FALSE, and TRUE.

    00391                    :
    00392
    00393     This function removes a specified entry from the the specified device
    00394     queue. If the device queue entry is not in the device queue, then no
    00395     operation is performed. Otherwise the specified device queue entry is
    00396     removed from the device queue and its inserted status is set to FALSE.
    00397
    00398 Arguments:
    00399
    00400     DeviceQueue - Supplies a pointer to a control object of type device queue.
    00401
    00402     DeviceQueueEntry - Supplies a pointer to a device queue entry which is to
    00403         be removed from its device queue.
    00404
    00405 Return Value:
    00406
    00407     A value of TRUE is returned if the device queue entry is removed from its
    00408     device queue. Otherwise a value of FALSE is returned.
    00409
    00410 --*/
    00411
    00412 {
    00413
    00414     KIRQL OldIrql;
    00415     BOOLEAN Removed;
    00416
    00417     ASSERT_DEVICE_QUEUE(DeviceQueue);
    00418     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00419
    00420     //
    00421     // Raise IRQL to dispatcher level and lock specified device queue.
    00422     //
    00423
    00424     ExAcquireSpinLock(&DeviceQueue->Lock, &OldIrql);
    00425
    00426     //
    00427     // If the device queue entry is not in a device queue, then no operation
    00428     // is performed. Otherwise remove the specified device queue entry from its
    00429     // device queue.
    00430     //
    00431
    00432     Removed = DeviceQueueEntry->Inserted;
    00433     if (Removed == TRUE) {
    00434         DeviceQueueEntry->Inserted = FALSE;
    00435         RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
    00436     }
    00437
    00438     //
    00439     // Unlock specified device queue, lower IRQL to its previous level, and
    00440     // return whether the device queue entry was removed from its queue.
    00441     //
    00442
    00443     ExReleaseSpinLock(&DeviceQueue->Lock, OldIrql);
    00444     return Removed;
    00445 }
    }

NTKERNELAPI PLIST_ENTRY KeRemoveQueue | ( | IN PRKQUEUE | Queue,
|  | IN KPROCESSOR_MODE | WaitMode,
|  | IN PLARGE_INTEGER Timeout | OPTIONAL
| ) |

Definition at line 238 of file queueobj.c.

References _KTHREAD::Alertable, APC_LEVEL, _KTHREAD::ApcState, ASSERT, ASSERT_QUEUE, DISPATCH_LEVEL, _KTIMER::DueTime, ExWorkerQueue, FALSE, _KTIMER::Header, KeBugCheckEx(), KeGetCurrentThread, _KAPC_STATE::KernelApcPending, KernelMode, KiActivateWaiterQueue(), KiComputeWaitInterval(), KiInsertTreeTimer(), KiInsertWaitList, KiLockDispatcherDatabase, KiSwapThread(), KiUnlockDispatcherDatabase(), _KWAIT_BLOCK::NextWaitBlock, NTSTATUS(), NULL, _KWAIT_BLOCK::Object, _KTHREAD::Queue, _KTHREAD::QueueListEntry, _KTHREAD::State, _KWAIT_BLOCK::Thread, _KTHREAD::Timer, TRUE, _KAPC_STATE::UserApcPending, _KTHREAD::WaitBlock, _KTHREAD::WaitBlockList, Waiting, _KTHREAD::WaitIrql, _KWAIT_BLOCK::WaitKey, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, _KTHREAD::WaitMode, _KTHREAD::WaitNext, _KTHREAD::WaitReason, _KTHREAD::WaitStatus, _KTHREAD::WaitTime, _KWAIT_BLOCK::WaitType, and WrQueue.

Referenced by ExpWorkerThread(), FsRtlWorkerThread(), and NtRemoveIoCompletion().

    00246                    :
    00247
    00248     This function removes the next entry from the Queue object entry
    00249     list. If no list entry is available, then the calling thread is
    00250     put in a wait state.
    00251
    00252     N.B. The wait discipline for Queue object LIFO.
    00253
    00254 Arguments:
    00255
    00256     Queue - Supplies a pointer to a dispatcher object of type Queue.
    00257
    00258     WaitMode  - Supplies the processor mode in which the wait is to occur.
    00259
    00260     Timeout - Supplies a pointer to an optional absolute of relative time over
    00261         which the wait is to occur.
    00262
    00263 Return Value:
    00264
    00265     The address of the entry removed from the Queue object entry list or
    00266     STATUS_TIMEOUT.
    00267
    00268     N.B. These values can easily be distinguished by the fact that all
    00269          addresses in kernel mode have the high order bit set.
    00270
    00271 --*/
    00272
    00273 {
    00274
    00275     LARGE_INTEGER DueTime;
    00276     PLIST_ENTRY Entry;
    00277     PRKTHREAD NextThread;
    00278     LARGE_INTEGER NewTime;
    00279     KIRQL OldIrql;
    00280     PRKQUEUE OldQueue;
    00281     PLARGE_INTEGER OriginalTime;
    00282     PRKTHREAD Thread;
    00283     PRKTIMER Timer;
    00284     PRKWAIT_BLOCK WaitBlock;
    00285     LONG_PTR WaitStatus;
    00286
    00287     ASSERT_QUEUE(Queue);
    00288     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00289
    00290     //
    00291     // If the dispatcher database lock is not already held, then set the wait
    00292     // IRQL and lock the dispatcher database. Else set boolean wait variable
    00293     // to FALSE.
    00294     //
    00295
    00296     Thread = KeGetCurrentThread();
    00297     if (Thread->WaitNext) {
    00298         Thread->WaitNext = FALSE;
    00299
    00300     } else {
    00301         KiLockDispatcherDatabase(&OldIrql);
    00302         Thread->WaitIrql = OldIrql;
    00303     }
    00304
    00305     //
    00306     // Check if the thread is currently processing a queue entry and whether
    00307     // the new queue is the same as the old queue.
    00308     //
    00309
    00310     OldQueue = Thread->Queue;
    00311     Thread->Queue = Queue;
    00312     if (Queue != OldQueue) {
    00313
    00314         //
    00315         // If the thread was previously associated with a queue, then remove
    00316         // the thread from the old queue object thread list and attempt to
    00317         // activate another thread.
    00318         //
    00319
    00320         Entry = &Thread->QueueListEntry;
    00321         if (OldQueue != NULL) {
    00322             RemoveEntryList(Entry);
    00323             KiActivateWaiterQueue(OldQueue);
    00324         }
    00325
    00326         //
    00327         // Insert thread in the thread list of the new queue that the thread
    00328         // will be associate with.
    00329         //
    00330
    00331         InsertTailList(&Queue->ThreadListHead, Entry);
    00332
    00333     } else {
    00334
    00335         //
    00336         // The previous and current queue are the same queue - decrement the
    00337         // current number of threads.
    00338         //
    00339
    00340         Queue->CurrentCount -= 1;
    00341     }
    00342
    00343     //
    00344     //
    00345     // Start of wait loop.
    00346     //
    00347     //
    00348     // Note this loop is repeated if a kernel APC is delivered in the
    00349     // middle of the wait or a kernel APC is pending on the first attempt
    00350     // through the loop.
    00351     //
    00352     // If the Queue object entry list is not empty, then remove the next
    00353     // entry from the Queue object entry list. Otherwise, wait for an entry
    00354     // to be inserted in the queue.
    00355     //
    00356
    00357     OriginalTime = Timeout;
    00358     do {
    00359
    00360         //
    00361         // Check if there is a queue entry available and the current
    00362         // number of active threads is less than target maximum number
    00363         // of threads.
    00364         //
    00365
    00366         Entry = Queue->EntryListHead.Flink;
    00367         if ((Entry != &Queue->EntryListHead) &&
    00368             (Queue->CurrentCount < Queue->MaximumCount)) {
    00369
    00370             //
    00371             // Decrement the number of entires in the Queue object entry list,
    00372             // increment the number of active threads, remove the next entry
    00373             // rom the list, and set the forward link to NULL.
    00374             //
    00375
    00376             Queue->Header.SignalState -= 1;
    00377             Queue->CurrentCount += 1;
    00378             if ((Entry->Flink == NULL) || (Entry->Blink == NULL)) {
    00379                 KeBugCheckEx(INVALID_WORK_QUEUE_ITEM,
    00380                              (ULONG_PTR)Entry,
    00381                              (ULONG_PTR)Queue,
    00382                              (ULONG_PTR)&ExWorkerQueue[0],
    00383                              (ULONG_PTR)((PWORK_QUEUE_ITEM)Entry)->WorkerRoutine);
    00384             }
    00385
    00386             RemoveEntryList(Entry);
    00387             Entry->Flink = NULL;
    00388             break;
    00389
    00390         } else {
    00391
    00392             //
    00393             // Set address of wait block list in thread object.
    00394             //
    00395
    00396             Thread->WaitBlockList = &Thread->WaitBlock[0];
    00397
    00398             //
    00399             // Test to determine if a kernel APC is pending.
    00400             //
    00401             // If a kernel APC is pending and the previous IRQL was less than
    00402             // APC_LEVEL, then a kernel APC was queued by another processor
    00403             // just after IRQL was raised to DISPATCH_LEVEL, but before the
    00404             // dispatcher database was locked.
    00405             //
    00406             // N.B. that this can only happen in a multiprocessor system.
    00407             //
    00408
    00409             if (Thread->ApcState.KernelApcPending && (Thread->WaitIrql < APC_LEVEL)) {
    00410
    00411                 //
    00412                 // Increment the current thread count, unlock the dispatcher
    00413                 // database, and lower IRQL to previous value. An APC interrupt
    00414                 // will immediately occur which will result in the delivery of
    00415                 // the kernel APC if possible.
    00416                 //
    00417
    00418                 Queue->CurrentCount += 1;
    00419                 KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00420
    00421             } else {
    00422
    00423                 //
    00424                 // Test if a user APC is pending.
    00425                 //
    00426
    00427                 if ((WaitMode != KernelMode) && (Thread->ApcState.UserApcPending)) {
    00428                     Entry = (PLIST_ENTRY)ULongToPtr(STATUS_USER_APC);
    00429                     Queue->CurrentCount += 1;
    00430                     break;
    00431                 }
    00432
    00433                 //
    00434                 // Construct a wait block and check to determine if the wait
    00435                 // is already satisfied. If the wait is satisfied, then perform
    00436                 // wait completion and return. Else put current thread in a
    00437                 // wait state if an explicit timeout value of zero is not
    00438                 // specified.
    00439                 //
    00440
    00441                 Thread->WaitStatus = (NTSTATUS)0;
    00442                 WaitBlock = &Thread->WaitBlock[0];
    00443                 WaitBlock->Object = (PVOID)Queue;
    00444                 WaitBlock->WaitKey = (CSHORT)(STATUS_SUCCESS);
    00445                 WaitBlock->WaitType = WaitAny;
    00446                 WaitBlock->Thread = Thread;
    00447
    00448                 //
    00449                 // Check to determine if a timeout value is specified.
    00450                 //
    00451
    00452                 if (ARGUMENT_PRESENT(Timeout)) {
    00453
    00454                     //
    00455                     // If the timeout value is zero, then return immediately
    00456                     // without waiting.
    00457                     //
    00458
    00459                     if (!(Timeout->LowPart | Timeout->HighPart)) {
    00460                         Entry = (PLIST_ENTRY)ULongToPtr(STATUS_TIMEOUT);
    00461                         Queue->CurrentCount += 1;
    00462                         break;
    00463                     }
    00464
    00465                     //
    00466                     // Initialize a wait block for the thread specific timer,
    00467                     // insert wait block in timer wait list, insert the timer
    00468                     // in the timer tree.
    00469                     //
    00470
    00471                     Timer = &Thread->Timer;
    00472                     WaitBlock->NextWaitBlock = &Thread->WaitBlock[1];
    00473                     WaitBlock = &Thread->WaitBlock[1];
    00474                     WaitBlock->Object = (PVOID)Timer;
    00475                     WaitBlock->WaitKey = (CSHORT)(STATUS_TIMEOUT);
    00476                     WaitBlock->WaitType = WaitAny;
    00477                     WaitBlock->Thread = Thread;
    00478                     Timer->Header.WaitListHead.Flink = &WaitBlock->WaitListEntry;
    00479                     Timer->Header.WaitListHead.Blink = &WaitBlock->WaitListEntry;
    00480                     WaitBlock->WaitListEntry.Flink = &Timer->Header.WaitListHead;
    00481                     WaitBlock->WaitListEntry.Blink = &Timer->Header.WaitListHead;
    00482                     if (KiInsertTreeTimer(Timer, *Timeout) == FALSE) {
    00483                         Entry = (PLIST_ENTRY)ULongToPtr(STATUS_TIMEOUT);
    00484                         Queue->CurrentCount += 1;
    00485                         break;
    00486                     }
    00487
    00488                     DueTime.QuadPart = Timer->DueTime.QuadPart;
    00489                 }
    00490
    00491                 //
    00492                 // Close up the circular list of wait control blocks.
    00493                 //
    00494
    00495                 WaitBlock->NextWaitBlock = &Thread->WaitBlock[0];
    00496
    00497                 //
    00498                 // Insert wait block in object wait list.
    00499                 //
    00500
    00501                 WaitBlock = &Thread->WaitBlock[0];
    00502                 InsertTailList(&Queue->Header.WaitListHead, &WaitBlock->WaitListEntry);
    00503
    00504                 //
    00505                 // Set the thread wait parameters, set the thread dispatcher
    00506                 // state to Waiting, and insert the thread in the wait list.
    00507                 //
    00508
    00509                 Thread->Alertable = FALSE;
    00510                 Thread->WaitMode = WaitMode;
    00511                 Thread->WaitReason = WrQueue;
    00512                 Thread->WaitTime = KiQueryLowTickCount();
    00513                 Thread->State = Waiting;
    00514                 KiInsertWaitList(WaitMode, Thread);
    00515
    00516                 //
    00517                 // Switch context to selected thread.
    00518                 //
    00519                 // Control is returned at the original IRQL.
    00520                 //
    00521
    00522                 ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
    00523
    00524                 WaitStatus = KiSwapThread();
    00525
    00526                 //
    00527                 // If the thread was not awakened to deliver a kernel mode APC,
    00528                 // then return wait status.
    00529                 //
    00530
    00531                 Thread->WaitReason = 0;
    00532                 if (WaitStatus != STATUS_KERNEL_APC) {
    00533                     return (PLIST_ENTRY)WaitStatus;
    00534                 }
    00535
    00536                 if (ARGUMENT_PRESENT(Timeout)) {
    00537
    00538                     //
    00539                     // Reduce the amount of time remaining before timeout occurs.
    00540                     //
    00541
    00542                     Timeout = KiComputeWaitInterval(OriginalTime,
    00543                                                     &DueTime,
    00544                                                     &NewTime);
    00545                 }
    00546             }
    00547
    00548             //
    00549             // Raise IRQL to DISPATCH_LEVEL, lock the dispatcher database,
    00550             // and decrement the count of active threads.
    00551             //
    00552
    00553             KiLockDispatcherDatabase(&OldIrql);
    00554             Thread->WaitIrql = OldIrql;
    00555             Queue->CurrentCount -= 1;
    00556         }
    00557
    00558     } while (TRUE);
    00559
    00560     //
    00561     // Unlock the dispatcher database and return the list entry address or a
    00562     // status of timeout.
    00563     //
    00564
    00565     KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00566     return Entry;
    00567 }

BOOLEAN KeRemoveQueueApc | ( | IN PKAPC | Apc | ) |

Definition at line 291 of file apcobj.c.

References _KAPC_STATE::ApcListHead, _KTHREAD::ApcQueueLock, _KTHREAD::ApcStatePointer, ASSERT, ASSERT_APC, DISPATCH_LEVEL, FALSE, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), PKAPC_STATE, and _KAPC_STATE::UserApcPending.

Referenced by CmNotifyRunDown(), ExTimerRundown(), NtCancelTimer(), and NtSetTimer().

    00297                    :
    00298
    00299     This function removes an APC object from an APC queue. If the APC object
    00300     is not in an APC queue, then no operation is performed. Otherwise the
    00301     APC object is removed from its current queue and its inserted state is
    00302     set FALSE.
    00303
    00304 Arguments:
    00305
    00306     Apc - Supplies a pointer to a control object of type APC.
    00307
    00308 Return Value:
    00309
    00310     If the APC object is not in an APC queue, then a value of FALSE is returned.
    00311     Otherwise a value of TRUE is returned.
    00312
    00313 --*/
    00314
    00315 {
    00316
    00317     PKAPC_STATE ApcState;
    00318     BOOLEAN Inserted;
    00319     KIRQL OldIrql;
    00320     PRKTHREAD Thread;
    00321
    00322     ASSERT_APC(Apc);
    00323     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00324
    00325     //
    00326     // Raise IRQL to dispatcher level, lock dispatcher database, and
    00327     // lock the APC queue.
    00328     //
    00329
    00330     Thread = Apc->Thread;
    00331     KiLockDispatcherDatabase(&OldIrql);
    00332     KiAcquireSpinLock(&Thread->ApcQueueLock);
    00333
    00334     //
    00335     // If the APC object is in an APC queue, then remove it from the queue
    00336     // and set its inserted state to FALSE. If the queue becomes empty, set
    00337     // the APC pending state to FALSE.
    00338     //
    00339
    00340     Inserted = Apc->Inserted;
    00341     if (Inserted != FALSE) {
    00342         Apc->Inserted = FALSE;
    00343         ApcState = Thread->ApcStatePointer[Apc->ApcStateIndex];
    00344         RemoveEntryList(&Apc->ApcListEntry);
    00345         if (IsListEmpty(&ApcState->ApcListHead[Apc->ApcMode]) != FALSE) {
    00346             if (Apc->ApcMode == KernelMode) {
    00347                 ApcState->KernelApcPending = FALSE;
    00348
    00349             } else {
    00350                 ApcState->UserApcPending = FALSE;
    00351             }
    00352         }
    00353     }
    00354
    00355     //
    00356     // Unlock the APC queue, unlock the dispatcher database, lower IRQL to
    00357     // its previous value, and return whether an APC object was removed from
    00358     // the APC queue.
    00359     //
    00360
    00361     KiReleaseSpinLock(&Thread->ApcQueueLock);
    00362     KiUnlockDispatcherDatabase(OldIrql);
    00363     return Inserted;
    00364 }
    }

NTKERNELAPI BOOLEAN KeRemoveQueueDpc | ( | IN PRKDPC | Dpc | ) |

Definition at line 272 of file dpcobj.c.

References ASSERT_DPC, Lock, and NULL.

Referenced by ExTimerRundown(), KiCalibrateTimeAdjustment(), NtCancelTimer(), and NtSetTimer().

    00278                    :
    00279
    00280     This function removes a DPC object from the DPC queue. If the DPC object
    00281     is not in the DPC queue, then no operation is performed. Otherwise, the
    00282     DPC object is removed from the DPC queue and its inserted state is set
    00283     FALSE.
    00284
    00285 Arguments:
    00286
    00287     Dpc - Supplies a pointer to a control object of type DPC.
    00288
    00289 Return Value:
    00290
    00291     If the DPC object is not in the DPC queue, then a value of FALSE is
    00292     returned. Otherwise a value of TRUE is returned.
    00293
    00294 --*/
    00295
    00296 {
    00297
    00298     PKSPIN_LOCK Lock;
    00299     PKPRCB Prcb;
    00300
    00301     ASSERT_DPC(Dpc);
    00302
    00303     //
    00304     // If the DPC object is in the DPC queue, then remove it from the queue
    00305     // and set its inserted state to FALSE.
    00306     //
    00307
    00308     _disable();
    00309     Lock = Dpc->Lock;
    00310     if (Lock != NULL) {
    00311
    00312         //
    00313         // Acquire the DPC lock of the target processor.
    00314         //
    00315
    00316 #if !defined(NT_UP)
    00317
    00318         KiAcquireSpinLock(Lock);
    00319
    00320 #endif
    00321
    00322         //
    00323         // If the specified DPC is still in the DPC queue, then remove
    00324         // it.
    00325         //
    00326         // N.B. It is possible for specified DPC to be removed from the
    00327         //      specified DPC queue before the DPC lock is obtained.
    00328         //
    00329         //
    00330
    00331         if (Lock == Dpc->Lock) {
    00332             Prcb = CONTAINING_RECORD(Lock, KPRCB, DpcLock);
    00333             Prcb->DpcQueueDepth -= 1;
    00334             RemoveEntryList(&Dpc->DpcListEntry);
    00335
    00336 #if defined(_ALPHA_) && !defined(NT_UP)
    00337
    00338             __MB();
    00339
    00340 #endif
    00341
    00342             Dpc->Lock = NULL;
    00343         }
    00344
    00345         //
    00346         // Release the DPC lock of the target processor.
    00347         //
    00348
    00349 #if !defined(NT_UP)
    00350
    00351         KiReleaseSpinLock(Lock);
    00352
    00353 #endif
    00354
    00355     }
    00356
    00357     //
    00358     // Enable interrupts and return whether the DPC was removed from a DPC
    00359     // queue.
    00360     //
    00361
    00362     _enable();
    00363     return (Lock != NULL);
    00364 }

NTKERNELAPI LONG KeResetEvent | ( | IN PRKEVENT | Event | ) |

Definition at line 285 of file eventobj.c.

References ASSERT, ASSERT_EVENT, DISPATCH_LEVEL, Event(), KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by IopSendMessageToTrackService(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtResetEvent(), SmbTraceStart(), SmbTraceThreadEntry(), SmbTraceToClient(), and xHalIoSetPartitionInformation().

    00291                    :
    00292
    00293     This function resets the signal state of an event object to
    00294     Not-Signaled. The previous state of the event object is returned
    00295     as the function value.
    00296
    00297 Arguments:
    00298
    00299     Event - Supplies a pointer to a dispatcher object of type event.
    00300
    00301 Return Value:
    00302
    00303     The previous signal state of the event object.
    00304
    00305 --*/
    00306
    00307 {
    00308
    00309     KIRQL OldIrql;
    00310     LONG OldState;
    00311
    00312     ASSERT_EVENT(Event);
    00313     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00314
    00315     //
    00316     // Raise IRQL to dispatcher level and lock dispatcher database.
    00317     //
    00318
    00319     KiLockDispatcherDatabase(&OldIrql);
    00320
    00321     //
    00322     // Capture the current signal state of event object and then reset
    00323     // the state of the event object to Not-Signaled.
    00324     //
    00325
    00326     OldState = Event->Header.SignalState;
    00327     Event->Header.SignalState = 0;
    00328
    00329     //
    00330     // Unlock the dispatcher database and lower IRQL to its previous
    00331     // value.
    00332
    00333     KiUnlockDispatcherDatabase(OldIrql);
    00334
    00335     //
    00336     // Return previous signal state of event object.
    00337     //
    00338
    00339     return OldState;
    00340 }

ULONG KeResumeThread | ( | IN PKTHREAD | Thread | ) |

Definition at line 1079 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), and RESUME_INCREMENT.

Referenced by NtResumeThread(), and PspCreateThread().

    01085                    :
    01086
    01087     This function resumes the execution of a suspended thread. If the
    01088     specified thread is not suspended, then no operation is performed.
    01089
    01090 Arguments:
    01091
    01092     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01093
    01094 Return Value:
    01095
    01096     The previous suspend count.
    01097
    01098 --*/
    01099
    01100 {
    01101
    01102     ULONG OldCount;
    01103     KIRQL OldIrql;
    01104
    01105     ASSERT_THREAD(Thread);
    01106     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01107
    01108     //
    01109     // Raise IRQL to dispatcher level and lock dispatcher database.
    01110     //
    01111
    01112     KiLockDispatcherDatabase(&OldIrql);
    01113
    01114     //
    01115     // Capture the current suspend count.
    01116     //
    01117
    01118     OldCount = Thread->SuspendCount;
    01119
    01120     //
    01121     // If the thread is currently suspended, then decrement its suspend count.
    01122     //
    01123
    01124     if (OldCount != 0) {
    01125         Thread->SuspendCount -= 1;
    01126
    01127         //
    01128         // If the resultant suspend count is zero and the freeze count is
    01129         // zero, then resume the thread by releasing its suspend semaphore.
    01130         //
    01131
    01132         if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) {
    01133             Thread->SuspendSemaphore.Header.SignalState += 1;
    01134             KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT);
    01135         }
    01136     }
    01137
    01138     //
    01139     // Unlock dispatcher database and lower IRQL to its previous
    01140     // value.
    01141     //
    01142
    01143     KiUnlockDispatcherDatabase(OldIrql);
    01144
    01145     //
    01146     // Return the previous suspend count.
    01147     //
    01148
    01149     return OldCount;
    01150 }

VOID KeReturnToFirmware | ( | IN FIRMWARE_REENTRY | Routine | ) |

Definition at line 499 of file ke/debug.c.

References FIRMWARE_REENTRY, and HalReturnToFirmware().

Referenced by IoWriteCrashDump().

    00505                    :
    00506
    00507     This routine will thaw all other processors in an MP environment to cause
    00508     them to return to do a return to firmware with the supplied parameter.
    00509
    00510     It will then call HalReturnToFirmware itself.
    00511
    00512     N.B. It is assumed that we are in the environment of the kernel debugger
    00513     or a crash dump.
    00514
    00515
    00516 Arguments:
    00517
    00518     Routine - What to invoke on return to firmware.
    00519
    00520 Return Value:
    00521
    00522     None.
    00523
    00524 --*/
    00525
    00526 {
    00527
    00528     //
    00529     // Just get the interface in now.  When intel and kenr come up with the
    00530     // right stuff we can fill this in.
    00531     //
    00532
    00533     HalReturnToFirmware(Routine);
    00534
    00535 }

VOID KeRevertToUserAffinityThread | ( | VOID |  | ) |

Definition at line 1153 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, FALSE, KeGetCurrentPrcb, KeGetCurrentThread, KiLockDispatcherDatabase, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Standby, _KTHREAD::State, _KTHREAD::SystemAffinityActive, and _KTHREAD::UserAffinity.

Referenced by CmpConfigureProcessors(), CmpInitializeMachineDependentConfiguration(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), KeSetup80387OrEmulate(), and KiInitMachineDependent().

    01159                    :
    01160
    01161     This function setss the affinity of the current thread to its user
    01162     affinity.
    01163
    01164 Arguments:
    01165
    01166     None.
    01167
    01168 Return Value:
    01169
    01170     None.
    01171
    01172 --*/
    01173
    01174 {
    01175
    01176     PRKTHREAD CurrentThread;
    01177     PRKTHREAD NextThread;
    01178     KIRQL OldIrql;
    01179     PKPRCB Prcb;
    01180
    01181     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01182     ASSERT(KeGetCurrentThread()->SystemAffinityActive != FALSE);
    01183
    01184     //
    01185     // Raise IRQL to dispatcher level and lock dispatcher database.
    01186     //
    01187
    01188     CurrentThread = KeGetCurrentThread();
    01189     KiLockDispatcherDatabase(&OldIrql);
    01190
    01191     //
    01192     // Set the current affinity to the user affinity.
    01193     //
    01194     // If the current processor is not in the new affinity set and another
    01195     // thread has not already been selected for execution on the current
    01196     // processor, then select a new thread for the current processor.
    01197     //
    01198
    01199     CurrentThread->Affinity = CurrentThread->UserAffinity;
    01200     CurrentThread->SystemAffinityActive = FALSE;
    01201     Prcb = KeGetCurrentPrcb();
    01202     if (((Prcb->SetMember & CurrentThread->Affinity) == 0) &&
    01203         (Prcb->NextThread == NULL)) {
    01204         NextThread = KiSelectNextThread(CurrentThread);
    01205         NextThread->State = Standby;
    01206         Prcb->NextThread = NextThread;
    01207     }
    01208
    01209     //
    01210     // Unlock dispatcher database and lower IRQL to its previous value.
    01211     //
    01212
    01213     KiUnlockDispatcherDatabase(OldIrql);
    01214     return;
    01215 }

PLIST_ENTRY KeRundownQueue | ( | IN PRKQUEUE | Queue | ) |

Definition at line 570 of file queueobj.c.

References ASSERT, ASSERT_QUEUE, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, and _KTHREAD::Queue.

Referenced by IopDeleteIoCompletion().

    00576                    :
    00577
    00578     This function runs down the specified queue by removing the listhead
    00579     from the queue list, removing any associated threads from the thread
    00580     list, and returning the address of the first entry.
    00581
    00582
    00583 Arguments:
    00584
    00585     Queue - Supplies a pointer to a dispatcher object of type Queue.
    00586
    00587 Return Value:
    00588
    00589     If the queue list is not empty, then the address of the first entry in
    00590     the queue is returned as the function value. Otherwise, a value of NULL
    00591     is returned.
    00592
    00593 --*/
    00594
    00595 {
    00596
    00597     PLIST_ENTRY Entry;
    00598     PLIST_ENTRY FirstEntry;
    00599     KIRQL OldIrql;
    00600     PKTHREAD Thread;
    00601
    00602     ASSERT_QUEUE(Queue);
    00603     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00604
    00605     //
    00606     // Raise IRQL to dispatch level and lock the dispatcher database.
    00607     //
    00608
    00609     KiLockDispatcherDatabase(&OldIrql);
    00610
    00611     //
    00612     // Get the address of the first entry in the queue and check if the
    00613     // list is empty or contains entries that should be flushed. If there
    00614     // are no entries in the list, then set the return value to NULL.
    00615     // Otherwise, set the return value to the address of the first list
    00616     // entry and remove the listhead from the list.
    00617     //
    00618
    00619     FirstEntry = Queue->EntryListHead.Flink;
    00620     if (FirstEntry == &Queue->EntryListHead) {
    00621         FirstEntry = NULL;
    00622
    00623     } else {
    00624         RemoveEntryList(&Queue->EntryListHead);
    00625     }
    00626
    00627     //
    00628     // Remove all associated threads from the thread list of the queue.
    00629     //
    00630
    00631     while (Queue->ThreadListHead.Flink != &Queue->ThreadListHead) {
    00632         Entry = Queue->ThreadListHead.Flink;
    00633         Thread = CONTAINING_RECORD(Entry, KTHREAD, QueueListEntry);
    00634         Thread->Queue = NULL;
    00635         RemoveEntryList(Entry);
    00636     }
    00637
    00638     //
    00639     // Unlock the dispatcher database, lower IRQL to its previous level,
    00640     // and return the function value.
    00641     //
    00642
    00643     KiUnlockDispatcherDatabase(OldIrql);
    00644     return FirstEntry;
    00645 }

VOID KeRundownThread | ( | VOID |  | ) |

VOID __cdecl KeSaveStateForHibernate | ( | IN PKPROCESSOR_STATE | ProcessorState | ) |

Definition at line 542 of file ke/i386/misc.c.

    00547                    :
    00548
    00549     Saves all processor-specific state that must be preserved
    00550     across an S4 state (hibernation).
    00551
    00552     N.B. #pragma surrounding this function is required in order
    00553          to create the frame pointer than RtlCaptureContext relies
    00554          on.
    00555     N.B. _CRTAPI1 (__cdecl) decoration is also required so that
    00556          RtlCaptureContext can compute the correct ESP.
    00557
    00558 Arguments:
    00559
    00560     ProcessorState - Supplies the KPROCESSOR_STATE where the
    00561         current CPU's state is to be saved.
    00562
    00563 Return Value:
    00564
    00565     None.
    00566
    00567 --*/
    00568
    00569 {
    00570     RtlCaptureContext(&ProcessorState->ContextFrame);
    00571     KiSaveProcessorControlState(ProcessorState);
    00572 }
    #pragma optimize( "y", off )    // disable frame pointer omission (FPO)

KAFFINITY KeSetAffinityThread | ( | IN PKTHREAD | Thread,
|  | IN KAFFINITY | Affinity
| ) |

Definition at line 1302 of file thredobj.c.

References _KPROCESS::Affinity, ASSERT, ASSERT_THREAD, ClearMember, DISPATCH_LEVEL, FALSE, INVALID_AFFINITY_SET, KeBugCheck(), KiDispatcherReadyListHead, KiLockDispatcherDatabase, KiProcessorBlock, KiReadySummary, KiReadyThread(), KiRequestDispatchInterrupt, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Ready, Running, Standby, and _KTHREAD::State.

Referenced by NtSetInformationProcess(), NtSetInformationThread(), and PspApplyJobLimitsToProcess().

    01309                    :
    01310
    01311     This function sets the affinity of a specified thread to a new
    01312     value. If the new affinity is not a proper subset of the parent
    01313     process affinity, or is null, then an error condition is raised.
    01314     If the specified thread is running on, or about to run on, a
    01315     processor for which it is no longer able to run, then the target
    01316     processor is rescheduled. If the specified thread is in a ready
    01317     state and is not in the parent process ready queue, then it is
    01318     rereadied to reevaluate any additional processors it may run on.
    01319
    01320 Arguments:
    01321
    01322     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01323
    01324     Affinity - Supplies the new of set of processors on which the thread
    01325         can run.
    01326
    01327 Return Value:
    01328
    01329     The previous affinity of the specified thread.
    01330
    01331 --*/
    01332
    01333 {
    01334
    01335     KAFFINITY OldAffinity;
    01336     KIRQL OldIrql;
    01337     PKPRCB Prcb;
    01338     PKPROCESS Process;
    01339     ULONG Processor;
    01340     KPRIORITY ThreadPriority;
    01341     PRKTHREAD Thread1;
    01342
    01343     ASSERT_THREAD(Thread);
    01344     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01345
    01346     //
    01347     // Raise IRQL to dispatcher level and lock dispatcher database.
    01348     //
    01349
    01350     KiLockDispatcherDatabase(&OldIrql);
    01351
    01352     //
    01353     // Capture the current affinity of the specified thread and get address
    01354     // of parent process object;
    01355     //
    01356
    01357     OldAffinity = Thread->UserAffinity;
    01358     Process = Thread->ApcStatePointer[0]->Process;
    01359
    01360     //
    01361     // If new affinity is not a proper subset of the parent process affinity,
    01362     // or the new affinity is null, then bugcheck.
    01363     //
    01364
    01365     if (((Affinity & Process->Affinity) != (Affinity)) || (!Affinity)) {
    01366         KeBugCheck(INVALID_AFFINITY_SET);
    01367     }
    01368
    01369     //
    01370     // Set the thread user affinity to the specified value.
    01371     //
    01372     // If the thread is not current executing with system affinity active,
    01373     // then set the thread current affinity and switch on the thread state.
    01374     //
    01375
    01376     Thread->UserAffinity = Affinity;
    01377     if (Thread->SystemAffinityActive == FALSE) {
    01378         Thread->Affinity = Affinity;
    01379         switch (Thread->State) {
    01380
    01381             //
    01382             // Ready State.
    01383             //
    01384             // If the thread is not in the process ready queue, then remove
    01385             // it from its current dispatcher ready queue and reready it for
    01386             // execution.
    01387             //
    01388
    01389         case Ready:
    01390             if (Thread->ProcessReadyQueue == FALSE) {
    01391                 RemoveEntryList(&Thread->WaitListEntry);
    01392                 ThreadPriority = Thread->Priority;
    01393                 if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority]) != FALSE) {
    01394                     ClearMember(ThreadPriority, KiReadySummary);
    01395                 }
    01396
    01397                 KiReadyThread(Thread);
    01398             }
    01399
    01400             break;
    01401
    01402             //
    01403             // Standby State.
    01404             //
    01405             // If the target processor is not in the new affinity set, then
    01406             // set the next thread to null for the target processor, select
    01407             // a new thread to run on the target processor, and reready the
    01408             // thread for execution.
    01409             //
    01410
    01411         case Standby:
    01412             Processor = Thread->NextProcessor;
    01413             Prcb = KiProcessorBlock[Processor];
    01414             if ((Prcb->SetMember & Affinity) == 0) {
    01415                 Prcb->NextThread = NULL;
    01416                 Thread1 = KiSelectNextThread(Thread);
    01417                 Thread1->State = Standby;
    01418                 Prcb->NextThread = Thread1;
    01419                 KiReadyThread(Thread);
    01420             }
    01421
    01422             break;
    01423
    01424             //
    01425             // Running State.
    01426             //
    01427             // If the target processor is not in the new affinity set and
    01428             // another thread has not already been selected for execution
    01429             // on the target processor, then select a new thread for the
    01430             // target processor, and cause the target processor to be
    01431             // redispatched.
    01432             //
    01433
    01434         case Running:
    01435             Processor = Thread->NextProcessor;
    01436             Prcb = KiProcessorBlock[Processor];
    01437             if (((Prcb->SetMember & Affinity) == 0) &&
    01438                 (Prcb->NextThread == NULL)) {
    01439                 Thread1 = KiSelectNextThread(Thread);
    01440                 Thread1->State = Standby;
    01441                 Prcb->NextThread = Thread1;
    01442                 KiRequestDispatchInterrupt(Processor);
    01443             }
    01444
    01445             break;
    01446
    01447             //
    01448             // Initialized, Terminated, Waiting, Transition case - For these
    01449             // states it is sufficient to just set the new thread affinity.
    01450             //
    01451
    01452         default:
    01453             break;
    01454         }
    01455     }
    01456
    01457     //
    01458     // Unlock dispatcher database, lower IRQL to its previous value, and
    01459     // return the previous user affinity.
    01460     //
    01461
    01462     KiUnlockDispatcherDatabase(OldIrql);
    01463     return OldAffinity;
    01464 }

BOOLEAN KeSetAutoAlignmentProcess | ( | IN PRKPROCESS | Process,
|  | IN BOOLEAN | Enable
| ) |

Definition at line 224 of file ia64/thredini.c.

    00231                    :
    00232
    00233     This function sets the data alignment handling mode for the specified
    00234     process and returns the previous data alignment handling mode.
    00235
    00236 Arguments:
    00237
    00238     Process  - Supplies a pointer to a dispatcher object of type process.
    00239
    00240     Enable - Supplies a boolean value that determines the handling of data
    00241         alignment exceptions for the process. A value of TRUE causes all
    00242         data alignment exceptions to be automatically handled by the kernel.
    00243         A value of FALSE causes all data alignment exceptions to be actually
    00244         raised as exceptions.
    00245
    00246 Return Value:
    00247
    00248     A value of TRUE is returned if data alignment exceptions were
    00249     previously automatically handled by the kernel. Otherwise, a value
    00250     of FALSE is returned.
    00251
    00252 --*/
    00253
    00254 {
    00255
    00256     KIRQL OldIrql;
    00257     BOOLEAN Previous;
    00258
    00259     ASSERT_PROCESS(Process);
    00260
    00261     //
    00262     // Raise IRQL to dispatcher level and lock dispatcher database.
    00263     //
    00264
    00265     KiLockDispatcherDatabase(&OldIrql);
    00266
    00267     //
    00268     // Capture the previous data alignment handling mode and set the
    00269     // specified data alignment mode.
    00270     //
    00271
    00272     Previous = Process->AutoAlignment;
    00273     Process->AutoAlignment = Enable;
    00274
    00275     //
    00276     // Unlock dispatcher database, lower IRQL to its previous value, and
    00277     // return the previous data alignment mode.
    00278     //
    00279
    00280     KiUnlockDispatcherDatabase(OldIrql);
    00281     return Previous;
    00282 }

BOOLEAN KeSetAutoAlignmentThread | ( | IN PKTHREAD | Thread,
|  | IN BOOLEAN | Enable
| ) |

Definition at line 269 of file alpha/thredini.c.

References ASSERT_THREAD, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtSetInformationThread().

    00276                    :
    00277
    00278     This function sets the data alignment handling mode for the specified
    00279     thread and returns the previous data alignment handling mode.
    00280
    00281 Arguments:
    00282
    00283     Thread  - Supplies a pointer to a dispatcher object of type thread.
    00284
    00285     Enable - Supplies a boolean value that determines the handling of data
    00286         alignment exceptions for the thread. A value of TRUE causes all
    00287         data alignment exceptions to be automatically handled by the kernel.
    00288         A value of FALSE causes all data alignment exceptions to be actually
    00289         raised as exceptions.
    00290
    00291 Return Value:
    00292
    00293     A value of TRUE is returned if data alignment exceptions were
    00294     previously automatically handled by the kernel. Otherwise, a value
    00295     of FALSE is returned.
    00296
    00297 --*/
    00298
    00299 {
    00300
    00301     KIRQL OldIrql;
    00302     BOOLEAN Previous;
    00303
    00304     ASSERT_THREAD(Thread);
    00305
    00306     //
    00307     // Raise IRQL to dispatcher level and lock dispatcher database.
    00308     //
    00309
    00310     KiLockDispatcherDatabase(&OldIrql);
    00311
    00312     //
    00313     // Capture the previous data alignment handling mode and set the
    00314     // specified data alignment mode.
    00315     //
    00316
    00317     Previous = Thread->AutoAlignment;
    00318     Thread->AutoAlignment = Enable;
    00319
    00320     //
    00321     // Unlock dispatcher database, lower IRQL to its previous value, and
    00322     // return the previous data alignment mode.
    00323     //
    00324
    00325     KiUnlockDispatcherDatabase(OldIrql);
    00326     return Previous;
    00327 }
    }

NTKERNELAPI LONG KeSetBasePriorityThread | ( | IN PKTHREAD | Thread,
|  | IN LONG | Increment
| ) |

Definition at line 1532 of file thredobj.c.

References abs, ASSERT, ASSERT_THREAD, _KPROCESS::BasePriority, DISPATCH_LEVEL, FALSE, Increment, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), and _KPROCESS::ThreadQuantum.

Referenced by ExpCreateWorkerThread(), ExpWorkerThreadBalanceManager(), and NtSetInformationThread().

    01539                    :
    01540
    01541     This function sets the base priority of the specified thread to a
    01542     new value.  The new base priority for the thread is the process base
    01543     priority plus the increment.
    01544
    01545 Arguments:
    01546
    01547     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01548
    01549     Increment - Supplies the base priority increment of the subject thread.
    01550
    01551         N.B. If the absolute value of the increment is such that saturation
    01552              of the base priority is forced, then subsequent changes to the
    01553              parent process base priority will not change the base priority
    01554              of the thread.
    01555
    01556 Return Value:
    01557
    01558     The previous base priority increment of the specified thread.
    01559
    01560 --*/
    01561
    01562 {
    01563
    01564     KPRIORITY NewBase;
    01565     KPRIORITY NewPriority;
    01566     KPRIORITY OldBase;
    01567     LONG OldIncrement;
    01568     KIRQL OldIrql;
    01569     PKPROCESS Process;
    01570
    01571     ASSERT_THREAD(Thread);
    01572     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01573
    01574     //
    01575     // Raise IRQL to dispatcher level and lock dispatcher database.
    01576     //
    01577
    01578     KiLockDispatcherDatabase(&OldIrql);
    01579
    01580     //
    01581     // Capture the base priority of the specified thread and determine
    01582     // whether saturation if being forced.
    01583     //
    01584
    01585     Process = Thread->ApcStatePointer[0]->Process;
    01586     OldBase = Thread->BasePriority;
    01587     OldIncrement = OldBase - Process->BasePriority;
    01588     if (Thread->Saturation != 0) {
    01589         OldIncrement = ((HIGH_PRIORITY + 1) / 2) * Thread->Saturation;
    01590     }
    01591
    01592     Thread->Saturation = FALSE;
    01593     if (abs(Increment) >= (HIGH_PRIORITY + 1) / 2) {
    01594         Thread->Saturation = (Increment > 0) ? 1 : -1;
    01595     }
    01596
    01597     //
    01598     // Set the base priority of the specified thread. If the thread's process
    01599     // is in the realtime class, then limit the change to the realtime class.
    01600     // Otherwise, limit the change to the variable class.
    01601     //
    01602
    01603     NewBase = Process->BasePriority + Increment;
    01604     if (Process->BasePriority >= LOW_REALTIME_PRIORITY) {
    01605         if (NewBase < LOW_REALTIME_PRIORITY) {
    01606             NewBase = LOW_REALTIME_PRIORITY;
    01607
    01608         } else if (NewBase > HIGH_PRIORITY) {
    01609             NewBase = HIGH_PRIORITY;
    01610         }
    01611
    01612         //
    01613         // Set the new priority of the thread to the new base priority.
    01614         //
    01615
    01616         NewPriority = NewBase;
    01617
    01618     } else {
    01619         if (NewBase >= LOW_REALTIME_PRIORITY) {
    01620             NewBase = LOW_REALTIME_PRIORITY - 1;
    01621
    01622         } else if (NewBase <= LOW_PRIORITY) {
    01623             NewBase = 1;
    01624         }
    01625
    01626         //
    01627         // Compute the new thread priority. If the new priority is outside
    01628         // the variable class, then set the new priority to the highest
    01629         // variable priority.
    01630         //
    01631
    01632         if (Thread->Saturation != 0) {
    01633             NewPriority = NewBase;
    01634
    01635         } else {
    01636             NewPriority = Thread->Priority +
    01637                             (NewBase - OldBase) - Thread->PriorityDecrement;
    01638
    01639             if (NewPriority >= LOW_REALTIME_PRIORITY) {
    01640                 NewPriority = LOW_REALTIME_PRIORITY - 1;
    01641             }
    01642         }
    01643     }
    01644
    01645     //
    01646     // Set the new base priority and clear the priority decrement. If the
    01647     // new priority is not equal to the old priority, then set the new thread
    01648     // priority.
    01649     //
    01650
    01651     Thread->BasePriority = (SCHAR)NewBase;
    01652     Thread->DecrementCount = 0;
    01653     Thread->PriorityDecrement = 0;
    01654     if (NewPriority != Thread->Priority) {
    01655         Thread->Quantum = Process->ThreadQuantum;
    01656         KiSetPriorityThread(Thread, NewPriority);
    01657     }
    01658
    01659     //
    01660     // Unlock dispatcher database and lower IRQL to its previous
    01661     // value.
    01662     //
    01663
    01664     KiUnlockDispatcherDatabase(OldIrql);
    01665
    01666     //
    01667     // Return the previous thread base priority.
    01668     //
    01669
    01670     return OldIncrement;
    01671 }

LOGICAL KeSetDisableBoostThread | ( | IN PKTHREAD | Thread,
|  | IN LOGICAL | Disable
| ) |

Definition at line 1674 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, KiLockDispatcherDatabase, and KiUnlockDispatcherDatabase().

Referenced by NtSetInformationProcess(), and NtSetInformationThread().

    01681                    :
    01682
    01683     This function disables priority boosts for the specified thread.
    01684
    01685 Arguments:
    01686
    01687     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01688
    01689     Disable - Supplies a logical value that determines whether priority
    01690         boosts for the thread are disabled or enabled.
    01691
    01692 Return Value:
    01693
    01694     The previous value of the disable boost state variable.
    01695
    01696 --*/
    01697
    01698 {
    01699
    01700     LOGICAL DisableBoost;
    01701     KIRQL OldIrql;
    01702
    01703     ASSERT_THREAD(Thread);
    01704     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01705
    01706     //
    01707     // Raise IRQL to dispatcher level and lock dispatcher database.
    01708     //
    01709
    01710     KiLockDispatcherDatabase(&OldIrql);
    01711
    01712     //
    01713     // Capture the current state of the disable boost variable and set its
    01714     // state to TRUE.
    01715     //
    01716
    01717     DisableBoost = Thread->DisableBoost;
    01718     Thread->DisableBoost = (BOOLEAN)Disable;
    01719
    01720     //
    01721     // Unlock dispatcher database and lower IRQL to its previous
    01722     // value.
    01723     //
    01724
    01725     KiUnlockDispatcherDatabase(OldIrql);
    01726
    01727     //
    01728     // Return the previous disable boost state.
    01729     //
    01730
    01731     return DisableBoost;
    01732 }

LOGICAL KeSetDisableQuantumProcess | ( | IN PKPROCESS | Process,
|  | IN LOGICAL | Disable
| ) |

Definition at line 907 of file procobj.c.

References ASSERT_PROCESS.

Referenced by PspApplyJobLimitsToProcess().

    00914                    :
    00915
    00916     This function disables quantum runout for realtime threads in the
    00917     specified process.
    00918
    00919 Arguments:
    00920
    00921     Process  - Supplies a pointer to a dispatcher object of type process.
    00922
    00923     Disable - Supplies a logical value that determines whether quantum
    00924         runout for realtime threads in the specified process are disabled
    00925         or enabled.
    00926
    00927 Return Value:
    00928
    00929     The previous value of the disable quantum state variable.
    00930
    00931 --*/
    00932
    00933 {
    00934
    00935     LOGICAL DisableQuantum;
    00936
    00937     ASSERT_PROCESS(Process);
    00938
    00939     //
    00940     // Capture the current state of the disable boost variable and set its
    00941     // state to TRUE.
    00942     //
    00943
    00944     DisableQuantum = Process->DisableQuantum;
    00945     Process->DisableQuantum = (BOOLEAN)Disable;
    00946
    00947     //
    00948     // Return the previous disable quantum state.
    00949     //
    00950
    00951     return DisableQuantum;
    00952 }

NTKERNELAPI VOID KeSetDmaIoCoherency | ( | IN ULONG | Attributes | ) |

Definition at line 239 of file ke/miscc.c.

References KiDmaIoCoherency.

    00245                    :
    00246
    00247     This function sets (enables/disables) DMA I/O coherency with data
    00248     caches.
    00249
    00250 Arguments:
    00251
    00252     Attributes - Supplies the set of DMA I/O coherency attributes for
    00253         the host system.
    00254
    00255 Return Value:
    00256
    00257     None.
    00258
    00259 --*/
    00260
    00261 {
    00262
    00263     KiDmaIoCoherency = Attributes;
    00264 }

NTKERNELAPI LONG KeSetEvent | ( | IN PRKEVENT | Event,
|  | IN KPRIORITY | Increment,
|  | IN BOOLEAN | Wait
| ) |

Definition at line 343 of file eventobj.c.

References ASSERT, ASSERT_EVENT, DISPATCH_LEVEL, Event(), FALSE, Increment, KeGetCurrentThread, KiLockDispatcherDatabase, KiSetEventCallData, KiUnlockDispatcherDatabase(), KiUnwaitThread(), KiWaitTest(), NTSTATUS(), RECORD_CALL_DATA, _KWAIT_BLOCK::Thread, _KTHREAD::WaitIrql, _KWAIT_BLOCK::WaitKey, _KTHREAD::WaitNext, and _KWAIT_BLOCK::WaitType.

Referenced by CancelPowerRequest(), CcDeleteSharedCacheMap(), CcFreeVirtualAddress(), CcGetVacbMiss(), CcInitializeCacheMap(), CcPostDeferredWrites(), CcUninitializeCacheMap(), CcWorkerThread(), CmNotifyRunDown(), CmpPostApc(), CmpPostApcRunDown(), CmpPostNotify(), DestroyDesktop(), DestroyTask(), DeviceCDROMNotify(), ExNotifyCallback(), ExpGetProcessInformation(), ExQueueWorkItem(), FreeDeviceInfo(), FreeWindowStation(), FsRecLoadFileSystem(), FsRtlCompletionRoutinePriv(), IoAcquireRemoveLockEx(), IopAcquireFileObjectLock(), IopCompleteRequest(), IopConnectLinkTrackingPort(), IopDeleteLockedDeviceNode(), IopDeviceActionWorker(), IopInvalidateRelationsInList(), IopLoadUnloadDriver(), IopLockDeviceRemovalRelations(), IopLockMountedDeviceForRemove(), IopMountVolume(), IopProcessStartDevices(), IopProcessStartDevicesWorker(), IopQueryRebalanceWorker(), IopSendMessageToTrackService(), IopTrackLink(), IopUnlockDeviceRemovalRelations(), IopUnlockMountedDeviceForRemove(), IopWarmEjectDevice(), IopXxxControlFile(), IoReleaseRemoveLockEx(), IoVerifyVolume(), KdpTimeSlipWork(), KeBalanceSetManager(), KiSetServerWaitClientEvent(), LfsFlushLfcb(), LpcpExtendPortZone(), LpcpFreeToPortZone(), LpcRequestPort(), LpcRequestWaitReplyPort(), MemPrint(), MemPrintFlush(), MiAllocatePoolPages(), MiCheckAndSetSystemTrimCriteria(), MiCheckControlArea(), MiCrashDumpWorker(), MiDereferenceSegmentThread(), MiDispatchFault(), MiEmptyAllWorkingSets(), MiEmptyAllWorkingSetsWorker(), MiFlushAllPages(), MiGatherMappedPages(), MiGatherPagefilePages(), MiInsertPageFileInList(), MiInsertPageInList(), MiInsertStandbyListAtFront(), MiModifiedPageWriterTimerDispatch(), MiObtainFreePages(), MiSegmentDelete(), MiUpdateModifiedWriterMdls(), MiWriteComplete(), MmCopyToCachedPage(), MmCopyVirtualMemory(), MmCreateSection(), MmResourcesAvailable(), MmShutdownSystem(), MmWorkingSetManager(), NtLockFile(), NtReadFile(), NtRequestPort(), NtRequestWaitReplyPort(), NtSecureConnectPort(), NtSetEvent(), NtSignalAndWaitForSingleObject(), NtWriteFile(), ProcessDeviceChanges(), PsEnforceExecutionTimeLimits(), PsLockProcess(), PspGetSetContextApc(), PspGetSetContextSpecialApc(), PspGetSetContextSpecialApcMain(), PsUnlockProcess(), QueueMouseEvent(), QueuePowerRequest(), RawInputThread(), RequestDeviceChange(), RtlAcquireRemoveLockEx(), RtlReleaseRemoveLock(), SetWakeBit(), SmbTraceCompleteRdr(), SmbTraceCompleteSrv(), SmbTraceEmptyQueue(), SmbTraceStop(), SmbTraceThreadEntry(), UdfMultiSyncCompletionRoutine(), UdfPnpCompletionRoutine(), UdfSingleSyncCompletionRoutine(), UserPowerStateCallout(), VdmpQueueIntNormalRoutine(), VerifierSetEvent(), WakeWowTask(), xxxButtonEvent(), xxxCreateDesktop(), xxxDesktopThread(), xxxGetInputEvent(), xxxSleepTask(), and xxxUserPowerCalloutWorker().

    00351                    :
    00352
    00353     This function sets the signal state of an event object to Signaled
    00354     and attempts to satisfy as many Waits as possible. The previous
    00355     signal state of the event object is returned as the function value.
    00356
    00357 Arguments:
    00358
    00359     Event - Supplies a pointer to a dispatcher object of type event.
    00360
    00361     Increment - Supplies the priority increment that is to be applied
    00362        if setting the event causes a Wait to be satisfied.
    00363
    00364     Wait - Supplies a boolean value that signifies whether the call to
    00365        KePulseEvent will be immediately followed by a call to one of the
    00366        kernel Wait functions.
    00367
    00368 Return Value:
    00369
    00370     The previous signal state of the event object.
    00371
    00372 --*/
    00373
    00374 {
    00375
    00376     KIRQL OldIrql;
    00377     LONG OldState;
    00378     PRKTHREAD Thread;
    00379     PRKWAIT_BLOCK WaitBlock;
    00380
    00381     ASSERT_EVENT(Event);
    00382     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00383
    00384     //
    00385     // Collect call data.
    00386     //
    00387
    00388 #if defined(_COLLECT_SET_EVENT_CALLDATA_)
    00389
    00390     RECORD_CALL_DATA(&KiSetEventCallData);
    00391
    00392 #endif
    00393
    00394     //
    00395     // Raise IRQL to dispatcher level and lock dispatcher database.
    00396     //
    00397
    00398     KiLockDispatcherDatabase(&OldIrql);
    00399
    00400     //
    00401     // If the wait list is empty, then set the state of the event to signaled.
    00402     // Otherwise, check if the wait can be satisfied immediately.
    00403     //
    00404
    00405     OldState = Event->Header.SignalState;
    00406     if (IsListEmpty(&Event->Header.WaitListHead) != FALSE) {
    00407         Event->Header.SignalState = 1;
    00408
    00409     } else {
    00410
    00411         //
    00412         // If the event is a notification event or the wait is not a wait any,
    00413         // then set the state of the event to signaled and attempt to satisfy
    00414         // as many waits as possible. Otherwise, the wait can be satisfied by
    00415         // directly unwaiting the thread.
    00416         //
    00417
    00418         WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
    00419                                       KWAIT_BLOCK,
    00420                                       WaitListEntry);
    00421
    00422         if ((Event->Header.Type == NotificationEvent) ||
    00423             (WaitBlock->WaitType != WaitAny)) {
    00424             if (OldState == 0) {
    00425                 Event->Header.SignalState = 1;
    00426                 KiWaitTest(Event, Increment);
    00427             }
    00428
    00429         } else {
    00430             KiUnwaitThread(WaitBlock->Thread, (NTSTATUS)WaitBlock->WaitKey, Increment);
    00431         }
    00432     }
    00433
    00434     //
    00435     // If the value of the Wait argument is TRUE, then return to the
    00436     // caller with IRQL raised and the dispatcher database locked. Else
    00437     // release the dispatcher database lock and lower IRQL to its
    00438     // previous value.
    00439     //
    00440
    00441     if (Wait != FALSE) {
    00442        Thread = KeGetCurrentThread();
    00443        Thread->WaitNext = Wait;
    00444        Thread->WaitIrql = OldIrql;
    00445
    00446     } else {
    00447        KiUnlockDispatcherDatabase(OldIrql);
    00448     }
    00449
    00450     //
    00451     // Return previous signal state of event object.
    00452     //
    00453
    00454     return OldState;
    00455 }

VOID KeSetEventBoostPriority | ( | IN PRKEVENT | Event,
|  | IN PRKTHREAD *Thread | OPTIONAL
| ) |

Definition at line 458 of file eventobj.c.

References _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, Event(), EVENT_INCREMENT, FALSE, Increment, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiUnwaitThread(), MmProductType, _KAPC_STATE::Process, _KTHREAD::Quantum, and _KPROCESS::ThreadQuantum.

Referenced by ExReleaseResourceForThreadLite(), and ExReleaseResourceLite().

    00465                    :
    00466
    00467     This function conditionally sets the signal state of an event object
    00468     to Signaled, and attempts to unwait the first waiter, and optionally
    00469     returns the thread address of the unwatied thread.
    00470
    00471     N.B. This function can only be called with synchronization events
    00472          and is primarily for the purpose of implementing fast mutexes.
    00473          It is assumed that the waiter is NEVER waiting on multiple
    00474          objects.
    00475
    00476 Arguments:
    00477
    00478     Event - Supplies a pointer to a dispatcher object of type event.
    00479
    00480     Thread - Supplies an optional pointer to a variable that receives
    00481         the address of the thread that is awakened.
    00482
    00483 Return Value:
    00484
    00485     None.
    00486
    00487 --*/
    00488
    00489 {
    00490
    00491     KPRIORITY Increment;
    00492     KIRQL OldIrql;
    00493     PRKTHREAD WaitThread;
    00494
    00495     ASSERT(Event->Header.Type == SynchronizationEvent);
    00496     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00497
    00498     //
    00499     // Raise IRQL to dispatcher level and lock dispatcher database.
    00500     //
    00501
    00502     KiLockDispatcherDatabase(&OldIrql);
    00503
    00504     //
    00505     // If the the wait list is not empty, then satisfy the wait of the
    00506     // first thread in the wait list. Otherwise, set the signal state
    00507     // of the event object.
    00508     //
    00509     // N.B. This function is only called for fast mutexes and exclusive
    00510     //      access to resources. All waits MUST be wait for single object.
    00511     //
    00512
    00513     if (IsListEmpty(&Event->Header.WaitListHead) != FALSE) {
    00514         Event->Header.SignalState = 1;
    00515
    00516     } else {
    00517
    00518         //
    00519         // Get the address of the waiting thread.
    00520         //
    00521
    00522         WaitThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
    00523                                        KWAIT_BLOCK,
    00524                                        WaitListEntry)->Thread;
    00525
    00526         //
    00527         // If specified, return the address of the thread that is awakened.
    00528         //
    00529
    00530         if (ARGUMENT_PRESENT(Thread)) {
    00531             *Thread = WaitThread;
    00532         }
    00533
    00534         //
    00535         // Give the new owner of the resource/fast mutex (the only callers) a
    00536         // full quantum, and unwait the thread with a standard event increment
    00537         // unless the system is a server system, in which case no boost if given.
    00538         //
    00539
    00540         WaitThread->Quantum = WaitThread->ApcState.Process->ThreadQuantum;
    00541         Increment = 0;
    00542         if (MmProductType == 0) {
    00543             Increment = EVENT_INCREMENT;
    00544         }
    00545
    00546         KiUnwaitThread(WaitThread, STATUS_SUCCESS, Increment);
    00547     }
    00548
    00549     //
    00550     // Unlock dispatcher database lock and lower IRQL to its previous
    00551     // value.
    00552     //
    00553
    00554     KiUnlockDispatcherDatabase(OldIrql);
    00555     return;
    00556 }
    }

NTKERNELAPI CCHAR KeSetIdealProcessorThread | ( | IN PKTHREAD | Thread,
|  | IN CCHAR | Processor
| ) |

Definition at line 1735 of file thredobj.c.

References ASSERT, KeNumberProcessors, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), MAXIMUM_PROCESSORS, and _KPROCESS::ThreadSeed.

Referenced by NtSetInformationThread().

    01742                    :
    01743
    01744     This function sets the ideal processor for the specified thread execution.
    01745
    01746 Arguments:
    01747
    01748     Thread - Supplies a pointer to the thread whose ideal processor number is
    01749         set to the specfied value.
    01750
    01751     Processor - Supplies the number of the ideal processor (the distinguished
    01752         value MAXIMUM_PROCESSORS indicates that there is no ideal processor).
    01753
    01754 Return Value:
    01755
    01756     The previous ideal processor number.
    01757
    01758 --*/
    01759
    01760 {
    01761
    01762     CCHAR OldProcessor;
    01763     KIRQL OldIrql;
    01764     PKPROCESS Process;
    01765
    01766     //
    01767     // Capture the previous ideal processor value, set the new ideal
    01768     // processor value, and return the old ideal processor value for the
    01769     // current thread;
    01770     //
    01771     // Note that this is done under the dispatcher lock in order to
    01772     // synchronize the updates with the other fields that share the
    01773     // same DWORD. Otherwise there is a granularity problem on Alpha.
    01774     //
    01775
    01776     ASSERT(Processor <= MAXIMUM_PROCESSORS);
    01777
    01778     KiLockDispatcherDatabase(&OldIrql);
    01779     OldProcessor = Thread->IdealProcessor;
    01780     if (Processor < MAXIMUM_PROCESSORS) {
    01781         Thread->IdealProcessor = Processor;
    01782
    01783     } else {
    01784         Process = Thread->ApcState.Process;
    01785         Process->ThreadSeed += 1;
    01786         Thread->IdealProcessor = (UCHAR)(Process->ThreadSeed % KeNumberProcessors);
    01787     }
    01788
    01789     //
    01790     // Unlock dispatcher database and lower IRQL to its previous
    01791     // value.
    01792     //
    01793
    01794     KiUnlockDispatcherDatabase(OldIrql);
    01795     return OldProcessor;
    01796 }

NTKERNELAPI VOID KeSetImportanceDpc | ( | IN PRKDPC | Dpc,
|  | IN KDPC_IMPORTANCE | Importance
| ) |

Definition at line 367 of file dpcobj.c.

References KDPC_IMPORTANCE.

    00374                    :
    00375
    00376     This function sets the importance of a DPC.
    00377
    00378 Arguments:
    00379
    00380     Dpc - Supplies a pointer to a control object of type DPC.
    00381
    00382     Number - Supplies the importance of the DPC.
    00383
    00384 Return Value:
    00385
    00386     None.
    00387
    00388 --*/
    00389
    00390 {
    00391
    00392     //
    00393     // Set the importance of the DPC.
    00394     //
    00395
    00396     Dpc->Importance = (UCHAR)Importance;
    00397     return;
    00398 }

VOID KeSetIntervalProfile | ( | IN ULONG | Interval,
|  | IN KPROFILE_SOURCE | Source
| ) |

Definition at line 223 of file profobj.c.

References HAL_PROFILE_SOURCE_INTERVAL, HalProfileSourceInterval, HalSetProfileInterval(), HalSetSystemInformation, _HAL_PROFILE_SOURCE_INTERVAL::Interval, KiIpiGenericCall(), KiProfileAlignmentFixupInterval, KiProfileInterval, and _HAL_PROFILE_SOURCE_INTERVAL::Source.

Referenced by NtSetIntervalProfile().

    00230                    :
    00231
    00232     This function sets the profile sampling interval. The interval is in
    00233     100ns units. The interval will actually be set to some value in a set
    00234     of preset values (at least on pc based hardware), using the one closest
    00235     to what the user asked for.
    00236
    00237 Arguments:
    00238
    00239     Interval - Supplies the length of the sampling interval in 100ns units.
    00240
    00241 Return Value:
    00242
    00243     None.
    00244
    00245 --*/
    00246
    00247 {
    00248
    00249     HAL_PROFILE_SOURCE_INTERVAL ProfileSourceInterval;
    00250
    00251     if (Source == ProfileTime) {
    00252
    00253         //
    00254         // If the specified sampling interval is less than the minimum
    00255         // sampling interval, then set the sampling interval to the minimum
    00256         // sampling interval.
    00257         //
    00258
    00259         if (Interval < MINIMUM_PROFILE_INTERVAL) {
    00260             Interval = MINIMUM_PROFILE_INTERVAL;
    00261         }
    00262
    00263         //
    00264         // Set the sampling interval.
    00265         //
    00266
    00267         KiProfileInterval = (ULONG)KiIpiGenericCall(HalSetProfileInterval, Interval);
    00268
    00269     } else if (Source == ProfileAlignmentFixup) {
    00270         KiProfileAlignmentFixupInterval = Interval;
    00271
    00272     } else {
    00273
    00274         //
    00275         // The HAL is responsible for setting this profile interval.
    00276         //
    00277
    00278         ProfileSourceInterval.Source = Source;
    00279         ProfileSourceInterval.Interval = Interval;
    00280         HalSetSystemInformation(HalProfileSourceInterval,
    00281                                 sizeof(HAL_PROFILE_SOURCE_INTERVAL),
    00282                                 &ProfileSourceInterval);
    00283     }
    00284
    00285     return;
    00286 }

NTKERNELAPI BOOLEAN KeSetKernelStackSwapEnable | ( | IN BOOLEAN | Enable | ) |

Definition at line 1799 of file thredobj.c.

References _KTHREAD::EnableStackSwap, and KeGetCurrentThread.

Referenced by ExpWorkerThread(), xxxDestroyThreadInfo(), and xxxInterSendMsgEx().

    01805                    :
    01806
    01807     This function sets the kernel stack swap enable value for the current
    01808     thread and returns the old swap enable value.
    01809
    01810 Arguments:
    01811
    01812     Enable - Supplies the new kernel stack swap enable value.
    01813
    01814 Return Value:
    01815
    01816     The previous kernel stack swap enable value.
    01817
    01818 --*/
    01819
    01820 {
    01821
    01822     BOOLEAN OldState;
    01823     PKTHREAD Thread;
    01824
    01825     //
    01826     // Capture the previous kernel stack swap enable value, set the new
    01827     // swap enable value, and return the old swap enable value for the
    01828     // current thread;
    01829     //
    01830
    01831     Thread = KeGetCurrentThread();
    01832     OldState = Thread->EnableStackSwap;
    01833     Thread->EnableStackSwap = Enable;
    01834     return OldState;
    01835 }

KPRIORITY KeSetPriorityProcess | ( | IN PKPROCESS | Process,
|  | IN KPRIORITY | BasePriority
| ) |

Definition at line 738 of file procobj.c.

References ASSERT, ASSERT_PROCESS, _KTHREAD::BasePriority, _KTHREAD::DecrementCount, DISPATCH_LEVEL, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), _KTHREAD::PriorityDecrement, _KTHREAD::Quantum, and _KTHREAD::Saturation.

Referenced by NtSetInformationProcess(), and PsSetProcessPriorityByClass().

    00745                    :
    00746
    00747     This function set the base priority of a process to a new value
    00748     and adjusts the priority and base priority of all child threads
    00749     as appropriate.
    00750
    00751 Arguments:
    00752
    00753     Process - Supplies a pointer to a dispatcher object of type process.
    00754
    00755     NewBase - Supplies the new base priority of the process.
    00756
    00757 Return Value:
    00758
    00759     The previous base priority of the process.
    00760
    00761 --*/
    00762
    00763 {
    00764
    00765     KPRIORITY Adjustment;
    00766     PLIST_ENTRY NextEntry;
    00767     KPRIORITY NewPriority;
    00768     KIRQL OldIrql;
    00769     KPRIORITY OldBase;
    00770     PKTHREAD Thread;
    00771
    00772     ASSERT_PROCESS(Process);
    00773     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00774
    00775     //
    00776     // Raise IRQL to dispatcher level and lock dispatcher database.
    00777     //
    00778
    00779     KiLockDispatcherDatabase(&OldIrql);
    00780
    00781     //
    00782     // Save the current process base priority, set the new process base
    00783     // priority, compute the adjustment value, and adjust the priority
    00784     // and base priority of all child threads as appropriate.
    00785     //
    00786
    00787     OldBase = Process->BasePriority;
    00788     Process->BasePriority = (SCHAR)NewBase;
    00789     Adjustment = NewBase - OldBase;
    00790     NextEntry = Process->ThreadListHead.Flink;
    00791     if (NewBase >= LOW_REALTIME_PRIORITY) {
    00792         while (NextEntry != &Process->ThreadListHead) {
    00793             Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
    00794
    00795             //
    00796             // Compute the new base priority of the thread.
    00797             //
    00798
    00799             NewPriority = Thread->BasePriority + Adjustment;
    00800
    00801             //
    00802             // If the new base priority is outside the realtime class,
    00803             // then limit the change to the realtime class.
    00804             //
    00805
    00806             if (NewPriority < LOW_REALTIME_PRIORITY) {
    00807                 NewPriority = LOW_REALTIME_PRIORITY;
    00808
    00809             } else if (NewPriority > HIGH_PRIORITY) {
    00810                 NewPriority = HIGH_PRIORITY;
    00811             }
    00812
    00813             //
    00814             // Set the base priority and the current priority of the
    00815             // thread to the appropriate value.
    00816             //
    00817             // N.B. If priority saturation occured the last time the thread
    00818             //      base priority was set and the new process base priority
    00819             //      is not crossing from variable to realtime, then it is not
    00820             //      necessary to change the thread priority.
    00821             //
    00822
    00823             if ((Thread->Saturation == 0) || (OldBase < LOW_REALTIME_PRIORITY)) {
    00824                 if (Thread->Saturation > 0) {
    00825                     NewPriority = HIGH_PRIORITY;
    00826
    00827                 } else if (Thread->Saturation < 0) {
    00828                     NewPriority = LOW_REALTIME_PRIORITY;
    00829                 }
    00830
    00831                 Thread->BasePriority = (SCHAR)NewPriority;
    00832                 Thread->Quantum = Process->ThreadQuantum;
    00833                 Thread->DecrementCount = 0;
    00834                 Thread->PriorityDecrement = 0;
    00835                 KiSetPriorityThread(Thread, NewPriority);
    00836             }
    00837
    00838             NextEntry = NextEntry->Flink;
    00839         }
    00840
    00841     } else {
    00842         while (NextEntry != &Process->ThreadListHead) {
    00843             Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
    00844
    00845             //
    00846             // Compute the new base priority of the thread.
    00847             //
    00848
    00849             NewPriority = Thread->BasePriority + Adjustment;
    00850
    00851             //
    00852             // If the new base priority is outside the variable class,
    00853             // then limit the change to the variable class.
    00854             //
    00855
    00856             if (NewPriority >= LOW_REALTIME_PRIORITY) {
    00857                 NewPriority = LOW_REALTIME_PRIORITY - 1;
    00858
    00859             } else if (NewPriority <= LOW_PRIORITY) {
    00860                 NewPriority = 1;
    00861             }
    00862
    00863             //
    00864             // Set the base priority and the current priority of the
    00865             // thread to the computed value and reset the thread quantum.
    00866             //
    00867             // N.B. If priority saturation occured the last time the thread
    00868             //      base priority was set and the new process base priority
    00869             //      is not crossing from realtime to variable, then it is not
    00870             //      necessary to change the thread priority.
    00871             //
    00872
    00873             if ((Thread->Saturation == 0) || (OldBase >= LOW_REALTIME_PRIORITY)) {
    00874                 if (Thread->Saturation > 0) {
    00875                     NewPriority = LOW_REALTIME_PRIORITY - 1;
    00876
    00877                 } else if (Thread->Saturation < 0) {
    00878                     NewPriority = 1;
    00879                 }
    00880
    00881                 Thread->BasePriority = (SCHAR)NewPriority;
    00882                 Thread->Quantum = Process->ThreadQuantum;
    00883                 Thread->DecrementCount = 0;
    00884                 Thread->PriorityDecrement = 0;
    00885                 KiSetPriorityThread(Thread, NewPriority);
    00886             }
    00887
    00888             NextEntry = NextEntry->Flink;
    00889         }
    00890     }
    00891
    00892     //
    00893     // Unlock dispatcher database and lower IRQL to its previous
    00894     // value.
    00895     //
    00896
    00897     KiUnlockDispatcherDatabase(OldIrql);
    00898
    00899     //
    00900     // Return previous process base priority
    00901     //
    00902
    00903     return OldBase;
    00904 }

NTKERNELAPI KPRIORITY KeSetPriorityThread | ( | IN PKTHREAD | Thread,
|  | IN KPRIORITY | Priority
| ) |

Definition at line 1838 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, FALSE, KiLockDispatcherDatabase, KiSetPriorityThread(), KiUnlockDispatcherDatabase(), and _KPROCESS::ThreadQuantum.

Referenced by FsRtlWorkerThread(), KeBalanceSetManager(), KeBoostCurrentThread(), KeSwapProcessOrStack(), KiInitializeKernel(), MiDereferenceSegmentThread(), MiMappedPageWriter(), MiModifiedPageWriter(), MmZeroPageThread(), NtSetInformationThread(), PspExitThread(), and zzzSetWindowsHookEx().

    01845                    :
    01846
    01847     This function sets the priority of the specified thread to a new value.
    01848     If the new thread priority is lower than the old thread priority, then
    01849     resecheduling may take place if the thread is currently running on, or
    01850     about to run on, a processor.
    01851
    01852 Arguments:
    01853
    01854     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01855
    01856     Priority - Supplies the new priority of the subject thread.
    01857
    01858 Return Value:
    01859
    01860     The previous priority of the specified thread.
    01861
    01862 --*/
    01863
    01864 {
    01865
    01866     KIRQL OldIrql;
    01867     KPRIORITY OldPriority;
    01868     PKPROCESS Process;
    01869
    01870     ASSERT_THREAD(Thread);
    01871     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01872     ASSERT(((Priority != 0) || (Thread->BasePriority == 0)) &&
    01873            (Priority <= HIGH_PRIORITY));
    01874
    01875     ASSERT(KeIsExecutingDpc() == FALSE);
    01876
    01877     //
    01878     // Raise IRQL to dispatcher level and lock dispatcher database.
    01879     //
    01880
    01881     KiLockDispatcherDatabase(&OldIrql);
    01882
    01883     //
    01884     // Capture the current thread priority, set the thread priority to the
    01885     // the new value, and replenish the thread quantum. It is assumed that
    01886     // the priority would not be set unless the thread had already lost it
    01887     // initial quantum.
    01888     //
    01889
    01890     OldPriority = Thread->Priority;
    01891     Process = Thread->ApcStatePointer[0]->Process;
    01892     Thread->Quantum = Process->ThreadQuantum;
    01893     Thread->DecrementCount = 0;
    01894     Thread->PriorityDecrement = 0;
    01895     KiSetPriorityThread(Thread, Priority);
    01896
    01897     //
    01898     // Unlock dispatcher database and lower IRQL to its previous
    01899     // value.
    01900     //
    01901
    01902     KiUnlockDispatcherDatabase(OldIrql);
    01903
    01904     //
    01905     // Return the previous thread priority.
    01906     //
    01907
    01908     return OldPriority;
    01909 }

LONG KeSetProcess | ( | IN PRKPROCESS | Process,
|  | IN KPRIORITY | Increment,
|  | IN BOOLEAN | Wait
| ) |

Definition at line 656 of file procobj.c.

References ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, Increment, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), _KTHREAD::WaitIrql, and _KTHREAD::WaitNext.

Referenced by PspExitProcess(), and PspExitThread().

    00664                    :
    00665
    00666     This function sets the signal state of a proces object to Signaled
    00667     and attempts to satisfy as many Waits as possible. The previous
    00668     signal state of the process object is returned as the function value.
    00669
    00670 Arguments:
    00671
    00672     Process - Supplies a pointer to a dispatcher object of type process.
    00673
    00674     Increment - Supplies the priority increment that is to be applied
    00675        if setting the process causes a Wait to be satisfied.
    00676
    00677     Wait - Supplies a boolean value that signifies whether the call to
    00678        KeSetProcess will be immediately followed by a call to one of the
    00679        kernel Wait functions.
    00680
    00681 Return Value:
    00682
    00683     The previous signal state of the process object.
    00684
    00685 --*/
    00686
    00687 {
    00688
    00689     KIRQL OldIrql;
    00690     LONG OldState;
    00691     PRKTHREAD Thread;
    00692
    00693     ASSERT_PROCESS(Process);
    00694     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00695
    00696     //
    00697     // Raise IRQL to dispatcher level and lock dispatcher database.
    00698     //
    00699
    00700     KiLockDispatcherDatabase(&OldIrql);
    00701
    00702     //
    00703     // If the previous state of the process object is Not-Signaled and
    00704     // the wait queue is not empty, then satisfy as many Waits as
    00705     // possible.
    00706     //
    00707
    00708     OldState = Process->Header.SignalState;
    00709     Process->Header.SignalState = 1;
    00710     if ((OldState == 0) && (!IsListEmpty(&Process->Header.WaitListHead))) {
    00711         KiWaitTest(Process, Increment);
    00712     }
    00713
    00714     //
    00715     // If the value of the Wait argument is TRUE, then return to the
    00716     // caller with IRQL raised and the dispatcher database locked. Else
    00717     // release the dispatcher database lock and lower IRQL to its
    00718     // previous value.
    00719     //
    00720
    00721     if (Wait) {
    00722         Thread = KeGetCurrentThread();
    00723         Thread->WaitNext = Wait;
    00724         Thread->WaitIrql = OldIrql;
    00725
    00726     } else {
    00727         KiUnlockDispatcherDatabase(OldIrql);
    00728     }
    00729
    00730     //
    00731     // Return previous signal state of process object.
    00732     //
    00733
    00734     return OldState;
    00735 }

NTKERNELAPI VOID FASTCALL KeSetSwapContextNotifyRoutine | ( | IN PSWAP_CONTEXT_NOTIFY_ROUTINE | NotifyRoutine | ) |

Definition at line 909 of file ke/miscc.c.

References KiSwapContextNotifyRoutine, and PAGED_CODE.

    00914                    :
    00915
    00916     This function sets the address of a callout routine which will be called
    00917     at each context swtich.
    00918
    00919 Arguments:
    00920
    00921     NotifyRoutine - Supplies the address of the swap context notify callout
    00922         routine.
    00923
    00924 Return Value:
    00925
    00926     None.
    00927
    00928 --*/
    00929
    00930 {
    00931
    00932     PAGED_CODE();
    00933
    00934     KiSwapContextNotifyRoutine = NotifyRoutine;
    00935     return;
    00936 }

VOID KeSetSystemAffinityThread | ( | IN KAFFINITY | Affinity | ) |

Definition at line 1467 of file thredobj.c.

References _KTHREAD::Affinity, ASSERT, DISPATCH_LEVEL, KeActiveProcessors, KeGetCurrentPrcb, KeGetCurrentThread, KiLockDispatcherDatabase, KiSelectNextThread(), KiUnlockDispatcherDatabase(), NULL, Standby, _KTHREAD::State, _KTHREAD::SystemAffinityActive, and TRUE.

Referenced by CmpConfigureProcessors(), CmpInitializeMachineDependentConfiguration(), Ke386CallBios(), KeConnectInterrupt(), KeDisconnectInterrupt(), KeSetSystemTime(), KeSetup80387OrEmulate(), and KiInitMachineDependent().

    01473                    :
    01474
    01475     This function set the system affinity of the current thread.
    01476
    01477 Arguments:
    01478
    01479     Affinity - Supplies the new of set of processors on which the thread
    01480         can run.
    01481
    01482 Return Value:
    01483
    01484     None.
    01485
    01486 --*/
    01487
    01488 {
    01489
    01490     PRKTHREAD CurrentThread;
    01491     PRKTHREAD NextThread;
    01492     KIRQL OldIrql;
    01493     PKPRCB Prcb;
    01494
    01495     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01496     ASSERT((Affinity & KeActiveProcessors) != 0);
    01497
    01498     //
    01499     // Raise IRQL to dispatcher level and lock dispatcher database.
    01500     //
    01501
    01502     CurrentThread = KeGetCurrentThread();
    01503     KiLockDispatcherDatabase(&OldIrql);
    01504
    01505     //
    01506     // Set the current affinity to the specified affinity.
    01507     //
    01508     // If the current processor is not in the new affinity set and another
    01509     // thread has not already been selected for execution on the current
    01510     // processor, then select a new thread for the current processor.
    01511     //
    01512
    01513     CurrentThread->Affinity = Affinity;
    01514     CurrentThread->SystemAffinityActive = TRUE;
    01515     Prcb = KeGetCurrentPrcb();
    01516     if (((Prcb->SetMember & CurrentThread->Affinity) == 0) &&
    01517         (Prcb->NextThread == NULL)) {
    01518         NextThread = KiSelectNextThread(CurrentThread);
    01519         NextThread->State = Standby;
    01520         Prcb->NextThread = NextThread;
    01521     }
    01522
    01523     //
    01524     // Unlock dispatcher database and lower IRQL to its previous value.
    01525     //
    01526
    01527     KiUnlockDispatcherDatabase(OldIrql);
    01528     return;
    01529 }

VOID KeSetSystemTime | ( | IN PLARGE_INTEGER | NewTime,
|  | OUT PLARGE_INTEGER | OldTime,
|  | IN BOOLEAN | AdjustInterruptTime,
|  | IN PLARGE_INTEGER HalTimeToSet | OPTIONAL
| ) |

Definition at line 335 of file ke/miscc.c.

References _DISPATCHER_HEADER::Absolute, ASSERT, DISPATCH_LEVEL, _KTIMER::DueTime, FALSE, HalSetRealTimeClock(), _KTIMER::Header, HIGH_LEVEL, Index, _DISPATCHER_HEADER::Inserted, KeBootTime, KeBootTimeBias, KeLowerIrql(), KeRaiseIrql(), KeRevertToUserAffinityThread(), KeSetSystemAffinityThread(), KiAdjustInterruptTime(), KiLockDispatcherDatabase, KiReinsertTreeTimer(), KiRemoveTreeTimer, KiTimerListExpire(), KiTimerTableListHead, KiUnlockDispatcherDatabase(), PoNotifySystemTimeSet(), RtlTimeToTimeFields(), TimeFields, TIMER_TABLE_SIZE, _KTIMER::TimerListEntry, and TRUE.

    00344                    :
    00345
    00346     This function sets the system time to the specified value and updates
    00347     timer queue entries to reflect the difference between the old system
    00348     time and the new system time.
    00349
    00350 Arguments:
    00351
    00352     NewTime - Supplies a pointer to a variable that specifies the new system
    00353         time.
    00354
    00355     OldTime - Supplies a pointer to a variable that will receive the previous
    00356         system time.
    00357
    00358     AdjustInterruptTime - If TRUE the amount of time being adjusted is
    00359         also applied to InterruptTime and TickCount.
    00360
    00361     HalTimeToSet - Supplies an optional time that if specified is to be used
    00362         to set the time in the realtime clock.
    00363
    00364 Return Value:
    00365
    00366     None.
    00367
    00368 --*/
    00369
    00370 {
    00371
    00372     LIST_ENTRY AbsoluteListHead;
    00373     LIST_ENTRY ExpiredListHead;
    00374     ULONG Index;
    00375     PLIST_ENTRY ListHead;
    00376     PLIST_ENTRY NextEntry;
    00377     KIRQL OldIrql1;
    00378     KIRQL OldIrql2;
    00379     LARGE_INTEGER TimeDelta;
    00380     TIME_FIELDS TimeFields;
    00381     PKTIMER Timer;
    00382
    00383     ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
    00384
    00385     //
    00386     // If a realtime clock value is specified, then convert the time value
    00387     // to time fields.
    00388     //
    00389
    00390     if (ARGUMENT_PRESENT(HalTimeToSet)) {
    00391         RtlTimeToTimeFields(HalTimeToSet, &TimeFields);
    00392     }
    00393
    00394     //
    00395     // Set affinity to the processor that keeps the system time, raise IRQL
    00396     // to dispatcher level and lock the dispatcher database, then raise IRQL
    00397     // to HIGH_LEVEL to synchronize with the clock interrupt routine.
    00398     //
    00399
    00400     KeSetSystemAffinityThread((KAFFINITY)1);
    00401     KiLockDispatcherDatabase(&OldIrql1);
    00402     KeRaiseIrql(HIGH_LEVEL, &OldIrql2);
    00403
    00404     //
    00405     // Save the previous system time, set the new system time, and set
    00406     // the realtime clock, if a time value is specified.
    00407     //
    00408
    00409     KiQuerySystemTime(OldTime);
    00410
    00411 #if defined(_WIN64)
    00412
    00413     SharedUserData->SystemHigh2Time = NewTime->HighPart;
    00414     SharedUserData->SystemLowTime = NewTime->LowPart;
    00415     SharedUserData->SystemHigh1Time = NewTime->HighPart;
    00416
    00417 #elif defined(ALPHA)
    00418
    00419     SharedUserData->SystemTime = *(PULONGLONG)NewTime;
    00420
    00421 #else
    00422
    00423     SharedUserData->SystemTime.High2Time = NewTime->HighPart;
    00424     SharedUserData->SystemTime.LowPart   = NewTime->LowPart;
    00425     SharedUserData->SystemTime.High1Time = NewTime->HighPart;
    00426
    00427 #endif // defined(ALPHA) || defined(_IA64_)
    00428
    00429     if (ARGUMENT_PRESENT(HalTimeToSet)) {
    00430         HalSetRealTimeClock(&TimeFields);
    00431     }
    00432
    00433     //
    00434     // Compute the difference between the previous system time and the new
    00435     // system time.
    00436     //
    00437
    00438     TimeDelta.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
    00439
    00440     //
    00441     // Update the boot time to reflect the delta. This keeps time based
    00442     // on boot time constant
    00443     //
    00444
    00445     KeBootTime.QuadPart = KeBootTime.QuadPart + TimeDelta.QuadPart;
    00446
    00447     //
    00448     // Track the overall bias applied to the boot time.
    00449     //
    00450
    00451     KeBootTimeBias = KeBootTimeBias + TimeDelta.QuadPart;
    00452
    00453     //
    00454     // Lower IRQL to dispatch level and if needed adjust the physical
    00455     // system interrupt time.
    00456     //
    00457
    00458     KeLowerIrql(OldIrql2);
    00459     if (AdjustInterruptTime) {
    00460
    00461         //
    00462         // Adjust the physical time of the system
    00463         //
    00464
    00465         AdjustInterruptTime = KiAdjustInterruptTime (TimeDelta.QuadPart);
    00466     }
    00467
    00468     //
    00469     // If the physical interrupt time of the system was not adjusted,
    00470     // recompute any absolute timers in the system for the new
    00471     // system time.
    00472     //
    00473
    00474     if (!AdjustInterruptTime) {
    00475
    00476         //
    00477         // Remove all absolute timers from the timer queue so their due time
    00478         // can be recomputed.
    00479         //
    00480
    00481         InitializeListHead(&AbsoluteListHead);
    00482         for (Index = 0; Index < TIMER_TABLE_SIZE; Index += 1) {
    00483             ListHead = &KiTimerTableListHead[Index];
    00484             NextEntry = ListHead->Flink;
    00485             while (NextEntry != ListHead) {
    00486                 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
    00487                 NextEntry = NextEntry->Flink;
    00488                 if (Timer->Header.Absolute != FALSE) {
    00489                     RemoveEntryList(&Timer->TimerListEntry);
    00490                     InsertTailList(&AbsoluteListHead, &Timer->TimerListEntry);
    00491                 }
    00492             }
    00493         }
    00494
    00495         //
    00496         // Recompute the due time and reinsert all absolute timers in the timer
    00497         // tree. If a timer has already expired, then insert the timer in the
    00498         // expired timer list.
    00499         //
    00500
    00501         InitializeListHead(&ExpiredListHead);
    00502         while (AbsoluteListHead.Flink != &AbsoluteListHead) {
    00503             Timer = CONTAINING_RECORD(AbsoluteListHead.Flink, KTIMER, TimerListEntry);
    00504             KiRemoveTreeTimer(Timer);
    00505             Timer->DueTime.QuadPart -= TimeDelta.QuadPart;
    00506             if (KiReinsertTreeTimer(Timer, Timer->DueTime) == FALSE) {
    00507                 Timer->Header.Inserted = TRUE;
    00508                 InsertTailList(&ExpiredListHead, &Timer->TimerListEntry);
    00509             }
    00510         }
    00511
    00512         //
    00513         // If any of the attempts to reinsert a timer failed, then timers have
    00514         // already expired and must be processed.
    00515         //
    00516         // N.B. The following function returns with the dispatcher database
    00517         //      unlocked.
    00518         //
    00519
    00520         KiTimerListExpire(&ExpiredListHead, OldIrql1);
    00521
    00522     } else {
    00523
    00524         KiUnlockDispatcherDatabase(OldIrql1);
    00525
    00526     }
    00527
    00528
    00529     //
    00530     // Set affinity back to its original value.
    00531     //
    00532
    00533     KeRevertToUserAffinityThread();
    00534
    00535     //
    00536     // Notify other components that the system time has been set
    00537     //
    00538
    00539     PoNotifySystemTimeSet();
    00540     return;
    00541 }

NTKERNELAPI VOID KeSetTargetProcessorDpc | ( | IN PRKDPC | Dpc,
|  | IN CCHAR | Number
| ) |

Definition at line 401 of file dpcobj.c.

References MAXIMUM_PROCESSORS.

    00408                    :
    00409
    00410     This function sets the processor number to which the DPC is targeted.
    00411
    00412 Arguments:
    00413
    00414     Dpc - Supplies a pointer to a control object of type DPC.
    00415
    00416     Number - Supplies the target processor number.
    00417
    00418 Return Value:
    00419
    00420     None.
    00421
    00422 --*/
    00423
    00424 {
    00425
    00426     //
    00427     // Set target processor number.
    00428     //
    00429     // The target processor number if biased by the maximum number of
    00430     // processors that are supported.
    00431     //
    00432
    00433     Dpc->Number = MAXIMUM_PROCESSORS + Number;
    00434     return;
    00435 }
    }

NTKERNELAPI VOID FASTCALL KeSetThreadSelectNotifyRoutine | ( | IN PTHREAD_SELECT_NOTIFY_ROUTINE | NotifyRoutine | ) |

Definition at line 940 of file ke/miscc.c.

References KiThreadSelectNotifyRoutine, and PAGED_CODE.

    00946                    :
    00947
    00948     This function sets the address of a callout routine which will be called
    00949     when a thread is being selected for execution.
    00950
    00951 Arguments:
    00952
    00953     NotifyRoutine - Supplies the address of the thread select notify callout
    00954         routine.
    00955
    00956 Return Value:
    00957
    00958     None.
    00959
    00960 --*/
    00961
    00962 {
    00963
    00964     PAGED_CODE();
    00965
    00966     KiThreadSelectNotifyRoutine = NotifyRoutine;
    00967     return;
    00968 }

NTKERNELAPI VOID KeSetTimeIncrement | ( | IN ULONG | MaximumIncrement,
|  | IN ULONG | MimimumIncrement
| ) |

Definition at line 779 of file ke/miscc.c.

References KeMaximumIncrement, KeMinimumIncrement, KeTimeAdjustment, KeTimeIncrement, KiTickOffset, and max.

    00786                    :
    00787
    00788     This function sets the time increment value in 100ns units. This
    00789     value is added to the system time at each interval clock interrupt.
    00790
    00791 Arguments:
    00792
    00793     MaximumIncrement - Supplies the maximum time between clock interrupts
    00794         in 100ns units supported by the host HAL.
    00795
    00796     MinimumIncrement - Supplies the minimum time between clock interrupts
    00797         in 100ns units supported by the host HAL.
    00798
    00799 Return Value:
    00800
    00801     None.
    00802
    00803 --*/
    00804
    00805 {
    00806
    00807     KeMaximumIncrement = MaximumIncrement;
    00808     KeMinimumIncrement = max(MinimumIncrement, 10 * 1000);
    00809     KeTimeAdjustment = MaximumIncrement;
    00810     KeTimeIncrement = MaximumIncrement;
    00811     KiTickOffset = MaximumIncrement;
    00812 }

NTKERNELAPI BOOLEAN KeSetTimer | ( | IN PKTIMER | Timer,
|  | IN LARGE_INTEGER | DueTime,
|  | IN PKDPC Dpc | OPTIONAL
| ) |

Definition at line 243 of file timerobj.c.

References KeSetTimerEx().

Referenced by CcCanIWrite(), CcScheduleLazyWriteScan(), CmpLazyFlush(), ExpWorkerThreadBalanceManager(), InternalSetTimer(), IopErrorLogQueueRequest(), KdpTimeSlipWork(), KeBalanceSetManager(), TimersProc(), and VdmpDelayInterrupt().

    00251                    :
    00252
    00253     This function sets a timer to expire at a specified time. If the timer is
    00254     already set, then it is implicitly canceled before it is set to expire at
    00255     the specified time. Setting a timer causes its due time to be computed,
    00256     its state to be set to Not-Signaled, and the timer object itself to be
    00257     inserted in the timer list.
    00258
    00259 Arguments:
    00260
    00261     Timer - Supplies a pointer to a dispatcher object of type timer.
    00262
    00263     DueTime - Supplies an absolute or relative time at which the timer
    00264         is to expire.
    00265
    00266     Dpc - Supplies an optional pointer to a control object of type DPC.
    00267
    00268 Return Value:
    00269
    00270     A boolean value of TRUE is returned if the the specified timer was
    00271     currently set. Else a value of FALSE is returned.
    00272
    00273 --*/
    00274
    00275 {
    00276
    00277     //
    00278     // Set the timer with a period of zero.
    00279     //
    00280
    00281     return KeSetTimerEx(Timer, DueTime, 0, Dpc);
    00282 }

NTKERNELAPI BOOLEAN KeSetTimerEx | ( | IN PKTIMER | Timer,
|  | IN LARGE_INTEGER | DueTime,
|  | IN LONG Period | OPTIONAL,
|  | IN PKDPC Dpc | OPTIONAL
| ) |

Definition at line 285 of file timerobj.c.

References ASSERT, ASSERT_TIMER, DISPATCH_LEVEL, _KTIMER::Dpc, FALSE, _KTIMER::Header, KeInsertQueueDpc(), KiInsertTreeTimer(), KiLockDispatcherDatabase, KiRemoveTreeTimer, KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KTIMER::Period, TIMER_EXPIRE_INCREMENT, and _DISPATCHER_HEADER::WaitListHead.

Referenced by IoInitSystem(), IovpInternalDeferredCompletion(), KeSetTimer(), MiInitializeSpecialPoolCriteria(), MiInsertPageInList(), MiModifiedPageWriterWorker(), and NtSetTimer().

    00294                    :
    00295
    00296     This function sets a timer to expire at a specified time. If the timer is
    00297     already set, then it is implicitly canceled before it is set to expire at
    00298     the specified time. Setting a timer causes its due time to be computed,
    00299     its state to be set to Not-Signaled, and the timer object itself to be
    00300     inserted in the timer list.
    00301
    00302 Arguments:
    00303
    00304     Timer - Supplies a pointer to a dispatcher object of type timer.
    00305
    00306     DueTime - Supplies an absolute or relative time at which the timer
    00307         is to expire.
    00308
    00309     Period - Supplies an optional period for the timer in milliseconds.
    00310
    00311     Dpc - Supplies an optional pointer to a control object of type DPC.
    00312
    00313 Return Value:
    00314
    00315     A boolean value of TRUE is returned if the the specified timer was
    00316     currently set. Else a value of FALSE is returned.
    00317
    00318 --*/
    00319
    00320 {
    00321
    00322     BOOLEAN Inserted;
    00323     LARGE_INTEGER Interval;
    00324     KIRQL OldIrql;
    00325     LARGE_INTEGER SystemTime;
    00326
    00327     ASSERT_TIMER(Timer);
    00328     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00329
    00330     //
    00331     // Raise IRQL to dispatcher level and lock dispatcher database.
    00332     //
    00333
    00334     KiLockDispatcherDatabase(&OldIrql);
    00335
    00336     //
    00337     // Capture the timer inserted status and if the timer is currently
    00338     // set, then remove it from the timer list.
    00339     //
    00340
    00341     Inserted = Timer->Header.Inserted;
    00342     if (Inserted != FALSE) {
    00343         KiRemoveTreeTimer(Timer);
    00344     }
    00345
    00346     //
    00347     // Clear the signal state, set the period, set the DPC address, and
    00348     // insert the timer in the timer tree. If the timer is not inserted
    00349     // in the timer tree, then it has already expired and as many waiters
    00350     // as possible should be continued, and a DPC, if specified should be
    00351     // queued.
    00352     //
    00353     // N.B. The signal state must be cleared in case the period is not
    00354     //      zero.
    00355     //
    00356
    00357     Timer->Header.SignalState = FALSE;
    00358     Timer->Dpc = Dpc;
    00359     Timer->Period = Period;
    00360     if (KiInsertTreeTimer((PRKTIMER)Timer, DueTime) == FALSE) {
    00361         if (IsListEmpty(&Timer->Header.WaitListHead) == FALSE) {
    00362             KiWaitTest(Timer, TIMER_EXPIRE_INCREMENT);
    00363         }
    00364
    00365         //
    00366         // If a DPC is specfied, then call the DPC routine.
    00367         //
    00368
    00369         if (Dpc != NULL) {
    00370             KiQuerySystemTime(&SystemTime);
    00371             KeInsertQueueDpc(Timer->Dpc,
    00372                              ULongToPtr(SystemTime.LowPart),
    00373                              ULongToPtr(SystemTime.HighPart));
    00374         }
    00375
    00376         //
    00377         // If the timer is periodic, then compute the next interval time
    00378         // and reinsert the timer in the timer tree.
    00379         //
    00380         // N.B. Even though the timer insertion is relative, it can still
    00381         //      fail if the period of the timer elapses in between computing
    00382         //      the time and inserting the timer in the table. If this happens,
    00383         //      try again.
    00384         //
    00385
    00386         if (Period != 0) {
    00387             Interval.QuadPart = Int32x32To64(Timer->Period, - 10 * 1000);
    00388             while (!KiInsertTreeTimer(Timer, Interval)) {
    00389                 ;
    00390             }
    00391         }
    00392     }
    00393
    00394     //
    00395     // Unlock the dispatcher database and lower IRQL to its previous
    00396     // value.
    00397     //
    00398
    00399     KiUnlockDispatcherDatabase(OldIrql);
    00400
    00401     //
    00402     // Return boolean value that signifies whether the timer was set of
    00403     // not.
    00404     //
    00405
    00406     return Inserted;
    00407 }

NTKERNELAPI VOID FASTCALL KeSetTimeUpdateNotifyRoutine | ( | IN PTIME_UPDATE_NOTIFY_ROUTINE | NotifyRoutine | ) |

Definition at line 972 of file ke/miscc.c.

References KiTimeUpdateNotifyRoutine, and PAGED_CODE.

    00978                    :
    00979
    00980     This function sets the address of a callout routine which will be called
    00981     each time the runtime for a thread is updated.
    00982
    00983 Arguments:
    00984
    00985     RoutineNotify - Supplies the address of the time update notify callout
    00986         routine.
    00987
    00988 Return Value:
    00989
    00990     None.
    00991
    00992 --*/
    00993
    00994 {
    00995
    00996     PAGED_CODE();
    00997
    00998     KiTimeUpdateNotifyRoutine = NotifyRoutine;
    00999     return;
    01000 }

NTKERNELAPI VOID KeStackAttachProcess | ( | IN PRKPROCESS | PROCESS,
|  | OUT PRKAPC_STATE | ApcState
| ) |

Definition at line 324 of file procobj.c.

References _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, ASSERT, ASSERT_PROCESS, DISPATCH_LEVEL, FALSE, KeBugCheckEx(), KeGetCurrentThread, KiAttachProcess(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), NULL, _KAPC_STATE::Process, and _KTHREAD::SavedApcState.

Referenced by NtClose(), NtSetInformationObject(), NtWaitForMultipleObjects(), ObpCreateHandle(), ObpCreateUnnamedHandle(), and PspProcessDelete().

    00331                    :
    00332
    00333     This function attaches a thread to a target process' address space
    00334     and returns information about a previous attached process.
    00335
    00336 Arguments:
    00337
    00338     Process - Supplies a pointer to a dispatcher object of type process.
    00339
    00340 Return Value:
    00341
    00342     None.
    00343
    00344 --*/
    00345
    00346 {
    00347
    00348     KIRQL OldIrql;
    00349     PRKTHREAD Thread;
    00350
    00351     ASSERT_PROCESS(Process);
    00352     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00353
    00354     //
    00355     // Raise IRQL to dispatcher level and lock dispatcher database.
    00356     //
    00357
    00358     Thread = KeGetCurrentThread();
    00359     KiLockDispatcherDatabase(&OldIrql);
    00360
    00361     //
    00362     // If the current thread is executing a DPC, then bug check.
    00363     //
    00364
    00365     if (KeIsExecutingDpc() != FALSE) {
    00366         KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
    00367                      (ULONG_PTR)Process,
    00368                      (ULONG_PTR)Thread->ApcState.Process,
    00369                      (ULONG)Thread->ApcStateIndex,
    00370                      (ULONG)KeIsExecutingDpc());
    00371     }
    00372
    00373     //
    00374     // If the target process is not the current process, then attach the target
    00375     // process. Otherwise, return a distinguished process value to indicate that
    00376     // an attach was not performed.
    00377     //
    00378
    00379     if (Thread->ApcState.Process == Process) {
    00380         KiUnlockDispatcherDatabase(OldIrql);
    00381         ApcState->Process = (PRKPROCESS)1;
    00382
    00383     } else {
    00384
    00385         //
    00386         // If the current thread is attached to a process, then save the current
    00387         // APC state in the callers APC state structure. Otherwise, save the
    00388         // current APC state in the saved APC state structure, and return a NULL
    00389         // process pointer.
    00390         //
    00391
    00392         if (Thread->ApcStateIndex != 0) {
    00393             KiAttachProcess(Thread, Process, OldIrql, ApcState);
    00394
    00395         } else {
    00396             KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
    00397             ApcState->Process = NULL;
    00398         }
    00399     }
    00400
    00401     return;
    00402 }

VOID KeStartAllProcessors | ( | VOID |  | ) |

Definition at line 78 of file alpha/allproc.c.

References _MEMORY_ALLOCATION_DESCRIPTOR::BasePage, BLOCK1_SIZE, BLOCK2_SIZE, _BOOT_STATUS::BootFinished, _RESTART_BLOCK::BootStatus, ExAllocatePool, ExFreePool(), FALSE, HalStartNextProcessor(), KeLoaderBlock, KeRegisteredProcessors, _LOADER_PARAMETER_BLOCK::KernelStack, KiAdjustInterruptTime(), KiBarrierWait, KiFreePcrPagesDescriptor, KiStartProcessor(), KSEG0_BASE, _MEMORY_ALLOCATION_DESCRIPTOR::ListEntry, LoaderOsloaderHeap, MAXIMUM_PROCESSORS, _LOADER_PARAMETER_BLOCK::MemoryDescriptorListHead, _MEMORY_ALLOCATION_DESCRIPTOR::MemoryType, NonPagedPool, NULL, PAGE_SHIFT, PAGE_SIZE, _MEMORY_ALLOCATION_DESCRIPTOR::PageCount, PMEMORY_ALLOCATION_DESCRIPTOR, _LOADER_PARAMETER_BLOCK::Prcb, ROUND_UP, _LOADER_PARAMETER_BLOCK::Thread, and _LOADER_PARAMETER_BLOCK::u.

    00084                    :
    00085
    00086     This function is called during phase 1 initialization on the master boot
    00087     processor to start all of the other registered processors.
    00088
    00089 Arguments:
    00090
    00091     None.
    00092
    00093 Return Value:
    00094
    00095     None.
    00096
    00097 --*/
    00098
    00099 {
    00100
    00101     ULONG_PTR MemoryBlock1;
    00102     ULONG_PTR MemoryBlock2;
    00103     ULONG Number;
    00104     ULONG PcrPage;
    00105     PKPRCB Prcb;
    00106     KPROCESSOR_STATE ProcessorState;
    00107     struct _RESTART_BLOCK *RestartBlock;
    00108     BOOLEAN Started;
    00109     LOGICAL SpecialPoolState;
    00110
    00111 #if !defined(NT_UP)
    00112
    00113     //
    00114     // If the registered number of processors is greater than the maximum
    00115     // number of processors supported, then only allow the maximum number
    00116     // of supported processors.
    00117     //
    00118
    00119     if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) {
    00120         KeRegisteredProcessors = MAXIMUM_PROCESSORS;
    00121     }
    00122
    00123     //
    00124     // Initialize the processor state that will be used to start each of
    00125     // processors. Each processor starts in the system initialization code
    00126     // with address of the loader parameter block as an argument.
    00127     //
    00128
    00129     RtlZeroMemory(&ProcessorState, sizeof(KPROCESSOR_STATE));
    00130     ProcessorState.ContextFrame.IntA0 = (ULONGLONG)(LONG_PTR)KeLoaderBlock;
    00131     ProcessorState.ContextFrame.Fir = (ULONGLONG)(LONG_PTR)KiStartProcessor;
    00132     Number = 1;
    00133     while (Number < KeRegisteredProcessors) {
    00134
    00135         //
    00136         // Allocate a DPC stack, an idle thread kernel stack, a panic
    00137         // stack, a PCR page, a processor block, and an executive thread
    00138         // object. If the allocation fails or the allocation cannot be
    00139         // made from unmapped nonpaged pool, then stop starting processors.
    00140         //
    00141         // Disable any special pooling that the user may have set in the
    00142         // registry as the next couple of allocations must come from KSEG0.
    00143         //
    00144
    00145         SpecialPoolState = MmSetSpecialPool(FALSE);
    00146         MemoryBlock1 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK1_SIZE);
    00147         if (IS_KSEG_ADDRESS(MemoryBlock1) == FALSE) {
    00148             MmSetSpecialPool(SpecialPoolState);
    00149             if ((PVOID)MemoryBlock1 != NULL) {
    00150                 ExFreePool((PVOID)MemoryBlock1);
    00151             }
    00152
    00153             break;
    00154         }
    00155
    00156         MemoryBlock2 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK2_SIZE);
    00157         if (IS_KSEG_ADDRESS(MemoryBlock2) == FALSE) {
    00158             MmSetSpecialPool(SpecialPoolState);
    00159             ExFreePool((PVOID)MemoryBlock1);
    00160             if ((PVOID)MemoryBlock2 != NULL) {
    00161                 ExFreePool((PVOID)MemoryBlock2);
    00162             }
    00163
    00164             break;
    00165         }
    00166
    00167         MmSetSpecialPool(SpecialPoolState);
    00168
    00169         //
    00170         // Zero both blocks of allocated memory.
    00171         //
    00172
    00173         RtlZeroMemory((PVOID)MemoryBlock1, BLOCK1_SIZE);
    00174         RtlZeroMemory((PVOID)MemoryBlock2, BLOCK2_SIZE);
    00175
    00176         //
    00177         // Set address of interrupt stack in loader parameter block.
    00178         //
    00179
    00180         KeLoaderBlock->u.Alpha.PanicStack =
    00181                         KSEG0_ADDRESS(MemoryBlock1 + (1 * KERNEL_STACK_SIZE));
    00182
    00183         //
    00184         // Set address of idle thread kernel stack in loader parameter block.
    00185         //
    00186
    00187         KeLoaderBlock->KernelStack =
    00188                         KSEG0_ADDRESS(MemoryBlock1 + (2 * KERNEL_STACK_SIZE));
    00189
    00190         ProcessorState.ContextFrame.IntSp =
    00191                             (ULONGLONG)(LONG_PTR)KeLoaderBlock->KernelStack;
    00192
    00193         //
    00194         // Set address of panic stack in loader parameter block.
    00195         //
    00196
    00197         KeLoaderBlock->u.Alpha.DpcStack =
    00198                         KSEG0_ADDRESS(MemoryBlock1 + (3 * KERNEL_STACK_SIZE));
    00199
    00200         //
    00201         // Set the page frame of the PCR page in the loader parameter block.
    00202         //
    00203
    00204         PcrPage = KSEG_PFN(MemoryBlock1 + (3 * KERNEL_STACK_SIZE));
    00205         KeLoaderBlock->u.Alpha.PcrPage = PcrPage;
    00206
    00207         //
    00208         // Set the address of the processor block and executive thread in the
    00209         // loader parameter block.
    00210         //
    00211
    00212         KeLoaderBlock->Prcb = KSEG0_ADDRESS((MemoryBlock2  + 63) & ~63);
    00213         KeLoaderBlock->Thread = KeLoaderBlock->Prcb + ROUND_UP(KPRCB);
    00214
    00215         //
    00216         // Attempt to start the next processor. If attempt is successful,
    00217         // then wait for the processor to get initialized. Otherwise,
    00218         // deallocate the processor resources and terminate the loop.
    00219         //
    00220
    00221         Started = HalStartNextProcessor(KeLoaderBlock, &ProcessorState);
    00222         if (Started == FALSE) {
    00223             ExFreePool((PVOID)MemoryBlock1);
    00224             ExFreePool((PVOID)MemoryBlock2);
    00225             break;
    00226
    00227         } else {
    00228
    00229             //
    00230             // Wait until boot is finished on the target processor before
    00231             // starting the next processor. Booting is considered to be
    00232             // finished when a processor completes its initialization and
    00233             // drops into the idle loop.
    00234             //
    00235
    00236             Prcb = (PKPRCB)(KeLoaderBlock->Prcb);
    00237             RestartBlock = Prcb->RestartBlock;
    00238             while (RestartBlock->BootStatus.BootFinished == 0) {
    00239                 KiMb();
    00240             }
    00241         }
    00242
    00243         Number += 1;
    00244     }
    00245
    00246 #endif
    00247
    00248     //
    00249     // Reset and synchronize the performance counters of all processors, by
    00250     // applying a null adjustment to the interrupt time
    00251     //
    00252
    00253     KiAdjustInterruptTime(0);
    00254     return;
    00255 }
    }

BOOLEAN KeStartProfile | ( | IN PKPROFILE | Profile,
|  | IN PULONG | Buffer
| ) |

Definition at line 289 of file profobj.c.

References _KACTIVE_PROFILE_SOURCE::Affinity, ASSERT, ASSERT_PROFILE, Buffer, DISPATCH_LEVEL, ExAllocatePoolWithTag, ExFreePool(), FALSE, HalStartProfileInterrupt(), KeGetCurrentPrcb, KeLowerIrql(), KeNumberProcessors, KeRaiseIrql(), KiEnableAlignmentExceptions, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiProfileAlignmentFixup, KiProfileIrql, KiProfileListHead, KiProfileLock, KiProfileSourceListHead, KiStartProfileInterrupt(), L, _KACTIVE_PROFILE_SOURCE::ListEntry, NonPagedPool, NULL, PKACTIVE_PROFILE_SOURCE, _KACTIVE_PROFILE_SOURCE::ProcessorCount, _KPROCESS::ProfileListHead, _KACTIVE_PROFILE_SOURCE::Source, and TRUE.

Referenced by NtStartProfile().

    00296                    :
    00297
    00298     This function starts profile data gathering on the specified profile
    00299     object. The profile object is marked started, and is registered with
    00300     the profile interrupt procedure.
    00301
    00302     If the number of active profile objects was previously zero, then the
    00303     profile interrupt is enabled.
    00304
    00305     N.B. For the current implementation, an arbitrary number of profile
    00306         objects may be active at once. This can present a large system
    00307         overhead. It is assumed that the caller appropriately limits the
    00308         the number of active profiles.
    00309
    00310 Arguments:
    00311
    00312     Profile - Supplies a pointer to a control object of type profile.
    00313
    00314     Buffer - Supplies a pointer to an array of counters, which record
    00315         the number of hits in the corresponding bucket.
    00316
    00317 Return Value:
    00318
    00319     A value of TRUE is returned if profiling was previously stopped for
    00320     the specified profile object. Otherwise, a value of FALSE is returned.
    00321
    00322 --*/
    00323
    00324 {
    00325
    00326     KIRQL OldIrql, OldIrql2;
    00327     PKPROCESS Process;
    00328     BOOLEAN Started;
    00329     KAFFINITY TargetProcessors;
    00330     PKPRCB Prcb;
    00331     PKACTIVE_PROFILE_SOURCE ActiveSource = NULL;
    00332     PKACTIVE_PROFILE_SOURCE CurrentActiveSource;
    00333     PKACTIVE_PROFILE_SOURCE AllocatedPool;
    00334     PLIST_ENTRY ListEntry;
    00335     ULONG SourceSize;
    00336     KAFFINITY AffinitySet;
    00337     PULONG Reference;
    00338
    00339     ASSERT_PROFILE(Profile);
    00340     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00341
    00342     //
    00343     // Allocate pool that may be required before raising to PROFILE_LEVEL.
    00344     //
    00345
    00346     SourceSize = sizeof(KACTIVE_PROFILE_SOURCE) + sizeof(ULONG) *
    00347                  (KeNumberProcessors - 1);
    00348     AllocatedPool = ExAllocatePoolWithTag(NonPagedPool, SourceSize, 'forP');
    00349     if (AllocatedPool == NULL) {
    00350         return(TRUE);
    00351     }
    00352
    00353     //
    00354     // Raise to dispatch level
    00355     //
    00356
    00357     KeRaiseIrql (DISPATCH_LEVEL, &OldIrql);
    00358     Prcb = KeGetCurrentPrcb();
    00359
    00360     //
    00361     // Raise IRQL to PROFILE_LEVEL and acquire the profile lock.
    00362     //
    00363
    00364     KeRaiseIrql(KiProfileIrql, &OldIrql2);
    00365     KiAcquireSpinLock(&KiProfileLock);
    00366
    00367     //
    00368     // Assume object already started
    00369     //
    00370
    00371     Started = FALSE;
    00372     AffinitySet = 0L;
    00373     TargetProcessors = 0L;
    00374
    00375     //
    00376     // If the specified profile object is not started, set started to TRUE,
    00377     // set the address of the profile buffer, set the profile object to started,
    00378     // insert the profile object in the appropriate profile list, and start
    00379     // profile interrupts if the number of active profile objects was previously zero.
    00380     //
    00381
    00382     if (Profile->Started == FALSE) {
    00383
    00384         Started = TRUE;
    00385         Profile->Buffer = Buffer;
    00386         Profile->Started = TRUE;
    00387         Process = Profile->Process;
    00388         if (Process != NULL) {
    00389             InsertTailList(&Process->ProfileListHead, &Profile->ProfileListEntry);
    00390
    00391         } else {
    00392             InsertTailList(&KiProfileListHead, &Profile->ProfileListEntry);
    00393         }
    00394
    00395         //
    00396         // Check the profile source list to see if this profile source is
    00397         // already started. If so, update the reference counts. If not,
    00398         // allocate a profile source object, initialize the reference
    00399         // counts, and add it to the list.
    00400         //
    00401
    00402         ListEntry = KiProfileSourceListHead.Flink;
    00403         while (ListEntry != &KiProfileSourceListHead) {
    00404             CurrentActiveSource = CONTAINING_RECORD(ListEntry,
    00405                                                     KACTIVE_PROFILE_SOURCE,
    00406                                                     ListEntry);
    00407
    00408             if (CurrentActiveSource->Source == Profile->Source) {
    00409                 ActiveSource = CurrentActiveSource;
    00410                 break;
    00411             }
    00412             ListEntry = ListEntry->Flink;
    00413         }
    00414
    00415         if (ActiveSource == NULL) {
    00416
    00417             //
    00418             // This source was not found, allocate and initialize a new entry and add
    00419             // it to the head of the list.
    00420             //
    00421
    00422             ActiveSource = AllocatedPool;
    00423             AllocatedPool = NULL;
    00424             RtlZeroMemory(ActiveSource, SourceSize);
    00425             ActiveSource->Source = Profile->Source;
    00426             InsertHeadList(&KiProfileSourceListHead, &ActiveSource->ListEntry);
    00427             if (Profile->Source == ProfileAlignmentFixup) {
    00428                 KiProfileAlignmentFixup = TRUE;
    00429             }
    00430         }
    00431
    00432         //
    00433         // Increment the reference counts for each processor in the
    00434         // affinity set.
    00435         //
    00436
    00437         AffinitySet = Profile->Affinity;
    00438         Reference = &ActiveSource->ProcessorCount[0];
    00439         while (AffinitySet != 0) {
    00440             if (AffinitySet & 1) {
    00441                 *Reference = *Reference + 1;
    00442             }
    00443
    00444             AffinitySet = AffinitySet >> 1;
    00445             Reference = Reference + 1;
    00446         }
    00447
    00448         //
    00449         // Compute the processors which the profile interrupt is
    00450         // required and not already started
    00451         //
    00452
    00453         AffinitySet = Profile->Affinity & ~ActiveSource->Affinity;
    00454         TargetProcessors = AffinitySet & ~Prcb->SetMember;
    00455
    00456         //
    00457         // Update set of processors on which this source is active.
    00458         //
    00459
    00460         ActiveSource->Affinity |= Profile->Affinity;
    00461     }
    00462
    00463     //
    00464     // Release the profile lock, lower IRQL to its previous value, and
    00465     // return whether profiling was started.
    00466     //
    00467
    00468     KiReleaseSpinLock(&KiProfileLock);
    00469     KeLowerIrql(OldIrql2);
    00470
    00471     //
    00472     // Start profile interrupt on pending processors
    00473     //
    00474
    00475 #if !defined(NT_UP)
    00476
    00477     if (TargetProcessors != 0) {
    00478         KiIpiSendPacket(TargetProcessors,
    00479                         KiStartProfileInterrupt,
    00480                         (PVOID)Profile->Source,
    00481                         NULL,
    00482                         NULL);
    00483     }
    00484
    00485 #endif
    00486
    00487     if (AffinitySet & Prcb->SetMember) {
    00488         if (Profile->Source == ProfileAlignmentFixup) {
    00489             KiEnableAlignmentExceptions();
    00490         }
    00491         HalStartProfileInterrupt(Profile->Source);
    00492     }
    00493
    00494 #if !defined(NT_UP)
    00495
    00496     if (TargetProcessors != 0) {
    00497         KiIpiStallOnPacketTargets(TargetProcessors);
    00498     }
    00499
    00500 #endif
    00501
    00502     //
    00503     // Lower to original IRQL
    00504     //
    00505
    00506     KeLowerIrql(OldIrql);
    00507
    00508     //
    00509     // If the allocated pool was not used, free it now.
    00510     //
    00511
    00512     if (AllocatedPool != NULL) {
    00513         ExFreePool(AllocatedPool);
    00514     }
    00515
    00516     return Started;
    00517 }

BOOLEAN KeStopProfile | ( | IN PKPROFILE | Profile | ) |

Definition at line 520 of file profobj.c.

References _KACTIVE_PROFILE_SOURCE::Affinity, ASSERT, ASSERT_PROFILE, DISPATCH_LEVEL, ExFreePool(), FALSE, HalStopProfileInterrupt(), KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiDisableAlignmentExceptions, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiProfileAlignmentFixup, KiProfileIrql, KiProfileLock, KiProfileSourceListHead, KiStopProfileInterrupt(), L, _KACTIVE_PROFILE_SOURCE::ListEntry, NULL, PKACTIVE_PROFILE_SOURCE, _KACTIVE_PROFILE_SOURCE::ProcessorCount, _KACTIVE_PROFILE_SOURCE::Source, and TRUE.

Referenced by ExpProfileDelete(), and NtStopProfile().

    00526                    :
    00527
    00528     This function stops profile data gathering on the specified profile
    00529     object. The object is marked stopped, and is removed from the active
    00530     profile list.
    00531
    00532     If the number of active profile objects goes to zero, then the profile
    00533     interrupt is disabled.
    00534
    00535 Arguments:
    00536
    00537     Profile - Supplies a pointer to a control object of type profile.
    00538
    00539 Return Value:
    00540
    00541     A value of TRUE is returned if profiling was previously started for
    00542     the specified profile object. Otherwise, a value of FALSE is returned.
    00543
    00544 --*/
    00545
    00546 {
    00547
    00548     KIRQL OldIrql, OldIrql2;
    00549     BOOLEAN Stopped;
    00550     KAFFINITY TargetProcessors;
    00551     PKPRCB Prcb;
    00552     BOOLEAN StopInterrupt = TRUE;
    00553     PLIST_ENTRY ListEntry;
    00554     PKACTIVE_PROFILE_SOURCE ActiveSource;
    00555     PKACTIVE_PROFILE_SOURCE PoolToFree=NULL;
    00556     KAFFINITY AffinitySet = 0;
    00557     KAFFINITY CurrentProcessor;
    00558     PULONG Reference;
    00559
    00560     ASSERT_PROFILE(Profile);
    00561     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00562
    00563     //
    00564     // Raise to disaptch level
    00565     //
    00566
    00567     KeRaiseIrql (DISPATCH_LEVEL, &OldIrql);
    00568     Prcb = KeGetCurrentPrcb();
    00569
    00570     //
    00571     // Raise IRQL to PROFILE_LEVEL and acquire the profile lock.
    00572     //
    00573
    00574     KeRaiseIrql(KiProfileIrql, &OldIrql2);
    00575     KiAcquireSpinLock(&KiProfileLock);
    00576
    00577     //
    00578     // Assume object already stopped
    00579     //
    00580
    00581     Stopped = FALSE;
    00582     AffinitySet = 0L;
    00583     TargetProcessors = 0L;
    00584
    00585     //
    00586     // If the specified profile object is not stopped, set stopped to TRUE, set
    00587     // the profile object to stopped, remove the profile object object from the
    00588     // appropriate profilelist, and stop profile interrupts if the number of
    00589     // active profile objects is zero.
    00590     //
    00591
    00592     if (Profile->Started != FALSE) {
    00593
    00594         Stopped = TRUE;
    00595         Profile->Started = FALSE;
    00596         RemoveEntryList(&Profile->ProfileListEntry);
    00597
    00598         //
    00599         // Search the profile source list to find the entry for this
    00600         // profile source.
    00601         //
    00602
    00603         ListEntry = KiProfileSourceListHead.Flink;
    00604         do {
    00605             ASSERT(ListEntry != &KiProfileSourceListHead);
    00606             ActiveSource = CONTAINING_RECORD(ListEntry,
    00607                                              KACTIVE_PROFILE_SOURCE,
    00608                                              ListEntry);
    00609             ListEntry = ListEntry->Flink;
    00610         } while ( ActiveSource->Source != Profile->Source );
    00611
    00612         //
    00613         // Decrement the reference counts for each processor in the
    00614         // affinity set and build up a mask of the processors that
    00615         // now have a reference count of zero.
    00616         //
    00617
    00618         CurrentProcessor = 1;
    00619         TargetProcessors = 0;
    00620         AffinitySet = Profile->Affinity;
    00621         Reference = &ActiveSource->ProcessorCount[0];
    00622         while (AffinitySet != 0) {
    00623             if (AffinitySet & 1) {
    00624                 *Reference = *Reference - 1;
    00625                 if (*Reference == 0) {
    00626                     TargetProcessors = TargetProcessors | CurrentProcessor;
    00627                 }
    00628             }
    00629
    00630             AffinitySet = AffinitySet >> 1;
    00631             Reference = Reference + 1;
    00632             CurrentProcessor = CurrentProcessor << 1;
    00633         }
    00634
    00635         //
    00636         // Compute the processors whose profile interrupt reference
    00637         // count has dropped to zero.
    00638         //
    00639
    00640         AffinitySet = TargetProcessors;
    00641         TargetProcessors = AffinitySet & ~Prcb->SetMember;
    00642
    00643         //
    00644         // Update set of processors on which this source is active.
    00645         //
    00646
    00647         ActiveSource->Affinity &= ~AffinitySet;
    00648
    00649         //
    00650         // Determine whether this profile source is stopped on all
    00651         // processors. If so, remove it from the list and free it.
    00652         //
    00653
    00654         if (ActiveSource->Affinity == 0) {
    00655             RemoveEntryList(&ActiveSource->ListEntry);
    00656             PoolToFree = ActiveSource;
    00657             if (Profile->Source == ProfileAlignmentFixup) {
    00658                 KiProfileAlignmentFixup = FALSE;
    00659             }
    00660         }
    00661     }
    00662
    00663     //
    00664     // Release the profile lock, lower IRQL to its previous value, and
    00665     // return whether profiling was stopped.
    00666     //
    00667
    00668     KiReleaseSpinLock(&KiProfileLock);
    00669     KeLowerIrql(OldIrql2);
    00670
    00671     //
    00672     // Stop profile interrupt on pending processors
    00673     //
    00674
    00675 #if !defined(NT_UP)
    00676
    00677     if (TargetProcessors != 0) {
    00678         KiIpiSendPacket(TargetProcessors,
    00679                         KiStopProfileInterrupt,
    00680                         (PVOID)Profile->Source,
    00681                         NULL,
    00682                         NULL);
    00683     }
    00684
    00685 #endif
    00686
    00687     if (AffinitySet & Prcb->SetMember) {
    00688         if (Profile->Source == ProfileAlignmentFixup) {
    00689             KiDisableAlignmentExceptions();
    00690         }
    00691         HalStopProfileInterrupt(Profile->Source);
    00692     }
    00693
    00694 #if !defined(NT_UP)
    00695
    00696     if (TargetProcessors != 0) {
    00697         KiIpiStallOnPacketTargets(TargetProcessors);
    00698     }
    00699
    00700 #endif
    00701
    00702     //
    00703     // Lower to original IRQL
    00704     //
    00705
    00706     KeLowerIrql (OldIrql);
    00707
    00708     //
    00709     // Now that IRQL has been lowered, free the profile source if
    00710     // necessary.
    00711     //
    00712
    00713     if (PoolToFree != NULL) {
    00714         ExFreePool(PoolToFree);
    00715     }
    00716
    00717     return Stopped;
    00718 }

ULONG KeSuspendThread | ( | IN | PKTHREAD | ) |

Definition at line 1912 of file thredobj.c.

References ASSERT, ASSERT_THREAD, DISPATCH_LEVEL, ExRaiseStatus(), FALSE, KiInsertQueueApc(), KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), and RESUME_INCREMENT.

Referenced by NtSuspendThread(), and PspCreateThread().

    01918                    :
    01919
    01920     This function suspends the execution of a thread. If the suspend count
    01921     overflows the maximum suspend count, then a condition is raised.
    01922
    01923 Arguments:
    01924
    01925     Thread  - Supplies a pointer to a dispatcher object of type thread.
    01926
    01927 Return Value:
    01928
    01929     The previous suspend count.
    01930
    01931 --*/
    01932
    01933 {
    01934
    01935     ULONG OldCount;
    01936     KIRQL OldIrql;
    01937
    01938     ASSERT_THREAD(Thread);
    01939     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    01940
    01941     //
    01942     // Raise IRQL to dispatcher level and lock dispatcher database.
    01943     //
    01944
    01945     KiLockDispatcherDatabase(&OldIrql);
    01946
    01947     //
    01948     // Capture the current suspend count.
    01949     //
    01950
    01951     OldCount = Thread->SuspendCount;
    01952
    01953     //
    01954     // If the suspend count is at its maximum value, then unlock dispatcher
    01955     // database, lower IRQL to its previous value, and raise an error
    01956     // condition.
    01957     //
    01958
    01959     if (OldCount == MAXIMUM_SUSPEND_COUNT) {
    01960
    01961         //
    01962         // Unlock the dispatcher database and raise an exception.
    01963         //
    01964
    01965         KiUnlockDispatcherDatabase(OldIrql);
    01966         ExRaiseStatus(STATUS_SUSPEND_COUNT_EXCEEDED);
    01967     }
    01968
    01969     //
    01970     // Increment the suspend count. If the thread was not previously suspended,
    01971     // then queue the thread's suspend APC.
    01972     //
    01973
    01974     Thread->SuspendCount += 1;
    01975     if ((OldCount == 0) && (Thread->FreezeCount == 0)) {
    01976         if (KiInsertQueueApc(&Thread->SuspendApc, RESUME_INCREMENT) == FALSE) {
    01977             Thread->SuspendSemaphore.Header.SignalState -= 1;
    01978         }
    01979     }
    01980
    01981     //
    01982     // Unlock dispatcher database and lower IRQL to its previous
    01983     // value.
    01984     //
    01985
    01986     KiUnlockDispatcherDatabase(OldIrql);
    01987
    01988     //
    01989     // Return the previous suspend count.
    01990     //
    01991
    01992     return OldCount;
    01993 }

VOID KeSwapProcessOrStack | ( | IN PVOID | Context | ) |

Definition at line 322 of file balmgr.c.

References Executive, FALSE, KeGetCurrentThread, KernelMode, KeSetPriorityThread(), KeWaitForSingleObject(), KiInSwapKernelStacks(), KiInSwapProcesses(), KiLockDispatcherDatabase, KiOutSwapKernelStacks(), KiOutSwapProcesses(), KiProcessInSwapListHead, KiProcessOutSwapListHead, KiStackInSwapListHead, KiStackOutSwapRequest, KiSwapEvent, KiUnlockDispatcherDatabase(), NTSTATUS(), NULL, Status, and TRUE.

Referenced by MmInitSystem().

    00328                    :
    00329
    00330     This thread controls the swapping of processes and kernel stacks. The
    00331     order of evaluation is:
    00332
    00333         Outswap kernel stacks
    00334         Outswap processes
    00335         Inswap processes
    00336         Inswap kernel stacks
    00337
    00338 Arguments:
    00339
    00340     Context - Supplies a pointer to the routine context - not used.
    00341
    00342 Return Value:
    00343
    00344     None.
    00345
    00346 --*/
    00347
    00348 {
    00349
    00350     KIRQL OldIrql;
    00351     NTSTATUS Status;
    00352
    00353     //
    00354     // Raise the thread priority to the lowest realtime level + 7 (i.e.,
    00355     // priority 23).
    00356     //
    00357
    00358     KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY + 7);
    00359
    00360     //
    00361     // Loop for ever processing swap events.
    00362     //
    00363
    00364     do {
    00365
    00366         //
    00367         // Wait for a swap event to occur.
    00368         //
    00369
    00370         Status = KeWaitForSingleObject(&KiSwapEvent,
    00371                                        Executive,
    00372                                        KernelMode,
    00373                                        FALSE,
    00374                                        NULL);
    00375
    00376         //
    00377         // Raise IRQL to dispatcher level and lock dispatcher database.
    00378         //
    00379
    00380         KiLockDispatcherDatabase(&OldIrql);
    00381
    00382         //
    00383         // Loop until all of the four possible actions cannot be initiated.
    00384         //
    00385
    00386         do {
    00387
    00388             //
    00389             // If a request has been made to out swap kernel stacks, then
    00390             // attempt to outswap kernel stacks. Otherwise, if the process
    00391             // out swap list is not empty, then initiate process outswapping.
    00392             // Otherwise, if the process inswap list is not empty, then start
    00393             // process inswapping. Otherwise, if the kernal stack inswap list
    00394             // is not active, then initiate kernel stack inswapping. Otherwise,
    00395             // no work is available.
    00396             //
    00397
    00398             if (KiStackOutSwapRequest != FALSE) {
    00399                 KiStackOutSwapRequest = FALSE;
    00400                 KiOutSwapKernelStacks(OldIrql);
    00401                 continue;
    00402
    00403             } else if (IsListEmpty(&KiProcessOutSwapListHead) == FALSE) {
    00404                 KiOutSwapProcesses(OldIrql);
    00405                 continue;
    00406
    00407             } else if (IsListEmpty(&KiProcessInSwapListHead) == FALSE) {
    00408                 KiInSwapProcesses(OldIrql);
    00409                 continue;
    00410
    00411             } else if (IsListEmpty(&KiStackInSwapListHead) == FALSE) {
    00412                 KiInSwapKernelStacks(OldIrql);
    00413                 continue;
    00414
    00415             } else {
    00416                 break;
    00417             }
    00418         } while (TRUE);
    00419
    00420         //
    00421         // Unlock the dispatcher database and lower IRQL to its previous
    00422         // value.
    00423         //
    00424
    00425         KiUnlockDispatcherDatabase(OldIrql);
    00426     } while (TRUE);
    00427     return;
    00428 }

KCONTINUE_STATUS KeSwitchFrozenProcessor | ( | IN ULONG | ProcessorNumber | ) |

Definition at line 334 of file ke/debug.c.

References ContinueError, ContinueNextProcessor, ContinueProcessorReselected, FREEZE_ACTIVE, FREEZE_OWNER, FrozenState, KeGetCurrentPrcb, KeNumberProcessors, KiProcessorBlock, and TARGET_FROZEN.

Referenced by KdpSendWaitContinue().

    00337 {
    00338 #if !defined(NT_UP)
    00339     PKPRCB TargetPrcb, CurrentPrcb;
    00340
    00341     //
    00342     // If Processor number is out of range, reselect current processor
    00343     //
    00344
    00345     if (ProcessorNumber >= (ULONG) KeNumberProcessors) {
    00346         return ContinueProcessorReselected;
    00347     }
    00348
    00349     TargetPrcb = KiProcessorBlock[ProcessorNumber];
    00350     CurrentPrcb = KeGetCurrentPrcb();
    00351
    00352     //
    00353     // Move active flag to correct processor.
    00354     //
    00355
    00356     CurrentPrcb->IpiFrozen &= ~FREEZE_ACTIVE;
    00357     TargetPrcb->IpiFrozen  |= FREEZE_ACTIVE;
    00358
    00359     //
    00360     // If this processor is frozen in KiFreezeTargetExecution, return to it
    00361     //
    00362
    00363     if (FrozenState(CurrentPrcb->IpiFrozen) == TARGET_FROZEN) {
    00364         return ContinueNextProcessor;
    00365     }
    00366
    00367     //
    00368     // This processor must be FREEZE_OWNER, wait to be reselected as the
    00369     // active processor
    00370     //
    00371
    00372     if (FrozenState(CurrentPrcb->IpiFrozen) != FREEZE_OWNER) {
    00373         return ContinueError;
    00374     }
    00375
    00376     while (!(CurrentPrcb->IpiFrozen & FREEZE_ACTIVE)) {
    00377         KeYieldProcessor();
    00378     }
    00379
    00380 #endif  // !defined(NT_UP)
    00381
    00382     //
    00383     // Reselect this processor
    00384     //
    00385
    00386     return ContinueProcessorReselected;
    00387 }

PVOID KeSwitchKernelStack | ( | IN PVOID | StackBase,
|  | IN PVOID | StackLimit
| ) |

| Referenced by PsConvertToGuiThread().

NTKERNELAPI BOOLEAN KeSynchronizeExecution | ( | IN PKINTERRUPT | Interrupt,
|  | IN PKSYNCHRONIZE_ROUTINE | SynchronizeRoutine,
|  | IN PVOID | SynchronizeContext
| ) |

| Referenced by VerifierSynchronizeExecution().

NTKERNELAPI VOID KeTerminateThread | ( | IN KPRIORITY | Increment | ) |

Definition at line 1996 of file thredobj.c.

References ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, ExWorkerQueue, FALSE, _KEVENT::Header, HyperCriticalWorkQueue, Increment, KeGetCurrentThread, KiActivateWaiterQueue(), KiInsertQueue(), KiLockDispatcherDatabase, KiProcessOutSwapListHead, KiRundownThread, KiSwapEvent, KiSwapThread(), KiWaitTest(), _WORK_QUEUE_ITEM::List, NULL, ProcessInTransition, PsReaperActive, PsReaperListHead, PsReaperWorkItem, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, Terminated, _ETHREAD::ThreadListEntry, _KPROCESS::ThreadListHead, TRUE, and _DISPATCHER_HEADER::WaitListHead.

Referenced by PspExitThread().

    02002                    :
    02003
    02004     This function terminates the execution of the current thread, sets the
    02005     signal state of the thread to Signaled, and attempts to satisfy as many
    02006     Waits as possible. The scheduling state of the thread is set to terminated,
    02007     and a new thread is selected to run on the current processor. There is no
    02008     return from this function.
    02009
    02010 Arguments:
    02011
    02012     None.
    02013
    02014 Return Value:
    02015
    02016     None.
    02017
    02018 --*/
    02019
    02020 {
    02021
    02022     PRKTHREAD NextThread;
    02023     KIRQL OldIrql;
    02024     PKPROCESS Process;
    02025     PRKQUEUE Queue;
    02026     PRKTHREAD Thread;
    02027
    02028     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    02029
    02030     //
    02031     // Raise IRQL to dispatcher level and lock dispatcher database.
    02032     //
    02033
    02034     Thread = KeGetCurrentThread();
    02035     KiLockDispatcherDatabase(&OldIrql);
    02036
    02037     //
    02038     // Insert the thread in the reaper list.
    02039     //
    02040     // If a reaper thread is not currently active, then insert a work item in
    02041     // the hyper critical work queue.
    02042     //
    02043     // N.B. This code has knowledge of the reaper data structures and how
    02044     //      worker threads are implemented.
    02045     //
    02046     // N.B. The dispatcher database lock is used to synchronize access to the
    02047     //      reaper list.
    02048     //
    02049
    02050     InsertTailList(&PsReaperListHead, &((PETHREAD)Thread)->TerminationPortList);
    02051     if (PsReaperActive == FALSE) {
    02052         PsReaperActive = TRUE;
    02053         KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
    02054                       &PsReaperWorkItem.List,
    02055                       FALSE);
    02056     }
    02057
    02058     //
    02059     // If the current thread is processing a queue entry, then remove
    02060     // the thrread from the queue object thread list and attempt to
    02061     // activate another thread that is blocked on the queue object.
    02062     //
    02063
    02064     Queue = Thread->Queue;
    02065     if (Queue != NULL) {
    02066         RemoveEntryList(&Thread->QueueListEntry);
    02067         KiActivateWaiterQueue(Queue);
    02068     }
    02069
    02070     //
    02071     // Set the state of the current thread object to Signaled, and attempt
    02072     // to satisfy as many Waits as possible.
    02073     //
    02074
    02075     Thread->Header.SignalState = TRUE;
    02076     if (IsListEmpty(&Thread->Header.WaitListHead) != TRUE) {
    02077         KiWaitTest((PVOID)Thread, Increment);
    02078     }
    02079
    02080     //
    02081     // Remove thread from its parent process' thread list.
    02082     //
    02083
    02084     RemoveEntryList(&Thread->ThreadListEntry);
    02085
    02086     //
    02087     // Set thread scheduling state to terminated, decrement the process'
    02088     // stack count, select a new thread to run on the current processor,
    02089     // and swap context to the new thread.
    02090     //
    02091
    02092     Thread->State = Terminated;
    02093     Process = Thread->ApcState.Process;
    02094     Process->StackCount -= 1;
    02095     if (Process->StackCount == 0) {
    02096         if (Process->ThreadListHead.Flink != &Process->ThreadListHead) {
    02097             Process->State = ProcessInTransition;
    02098             InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry);
    02099             KiSwapEvent.Header.SignalState = 1;
    02100             if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
    02101                 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
    02102             }
    02103         }
    02104     }
    02105
    02106     //
    02107     // Rundown any architectural specific structures
    02108     //
    02109
    02110     KiRundownThread(Thread);
    02111
    02112     //
    02113     // Get off the processor for the last time.
    02114     //
    02115
    02116     KiSwapThread();
    02117     return;
    02118 }

BOOLEAN KeTestAlertThread | ( | IN | KPROCESSOR_MODE | ) |

Definition at line 2121 of file thredobj.c.

References _KTHREAD::Alerted, _KAPC_STATE::ApcListHead, _KTHREAD::ApcQueueLock, _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, FALSE, KeGetCurrentThread, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), TRUE, _KAPC_STATE::UserApcPending, and UserMode.

Referenced by KiDeliverApc(), and NtTestAlert().

    02127                    :
    02128
    02129     This function tests to determine if the alerted variable for the
    02130     specified processor mode has a value of TRUE or whether a user mode
    02131     APC should be delivered to the current thread.
    02132
    02133 Arguments:
    02134
    02135     AlertMode - Supplies the processor mode which is to be tested
    02136         for an alerted condition.
    02137
    02138 Return Value:
    02139
    02140     The previous state of the alerted variable for the specified processor
    02141     mode.
    02142
    02143 --*/
    02144
    02145 {
    02146
    02147     BOOLEAN Alerted;
    02148     KIRQL OldIrql;
    02149     PKTHREAD Thread;
    02150
    02151     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    02152
    02153     //
    02154     // Raise IRQL to dispatcher level, lock dispatcher database, and lock
    02155     // APC queue.
    02156     //
    02157
    02158     Thread = KeGetCurrentThread();
    02159     KiLockDispatcherDatabase(&OldIrql);
    02160     KiAcquireSpinLock(&Thread->ApcQueueLock);
    02161
    02162     //
    02163     // If the current thread is alerted for the specified processor mode,
    02164     // then clear the alerted state. Else if the specified processor mode
    02165     // is user and the current thread's user mode APC queue contains an entry,
    02166     // then set user APC pending.
    02167     //
    02168
    02169     Alerted = Thread->Alerted[AlertMode];
    02170     if (Alerted == TRUE) {
    02171         Thread->Alerted[AlertMode] = FALSE;
    02172
    02173     } else if ((AlertMode == UserMode) &&
    02174               (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) != TRUE)) {
    02175         Thread->ApcState.UserApcPending = TRUE;
    02176     }
    02177
    02178     //
    02179     // Unlock APC queue, unlock dispatcher database, lower IRQL to its
    02180     // previous value, and return the previous alerted state for the
    02181     // specified mode.
    02182     //
    02183
    02184     KiReleaseSpinLock(&Thread->ApcQueueLock);
    02185     KiUnlockDispatcherDatabase(OldIrql);
    02186     return Alerted;
    02187 }

VOID KeThawAllThreads | ( | VOID |  | ) |

Definition at line 2190 of file thredobj.c.

References ASSERT, DISPATCH_LEVEL, _KTHREAD::FreezeCount, _KSEMAPHORE::Header, KeGetCurrentThread, KeLeaveCriticalRegion, KiLockDispatcherDatabase, KiUnlockDispatcherDatabase(), KiWaitTest(), RESUME_INCREMENT, _DISPATCHER_HEADER::SignalState, _KTHREAD::SuspendCount, _KTHREAD::SuspendSemaphore, and _KPROCESS::ThreadListHead.

Referenced by DbgkpResumeProcess().

    02196                    :
    02197
    02198     This function resumes the execution of all suspended froozen threads
    02199     in the current process.
    02200
    02201 Arguments:
    02202
    02203     None.
    02204
    02205 Return Value:
    02206
    02207     None.
    02208
    02209 --*/
    02210
    02211 {
    02212
    02213     PLIST_ENTRY ListHead;
    02214     PLIST_ENTRY NextEntry;
    02215     PKPROCESS Process;
    02216     PKTHREAD Thread;
    02217     ULONG OldCount;
    02218     KIRQL OldIrql;
    02219
    02220     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    02221
    02222     //
    02223     // Get the address of the current current process object, raise IRQL
    02224     // to dispatch level, lock dispatcher database, and thaw the execution
    02225     // of all threads in the current process that have been frozzen.
    02226     //
    02227
    02228     Process = KeGetCurrentThread()->ApcState.Process;
    02229     KiLockDispatcherDatabase(&OldIrql);
    02230     ListHead = &Process->ThreadListHead;
    02231     NextEntry = ListHead->Flink;
    02232     do {
    02233
    02234         //
    02235         // Get the address of the next thread and thaw its execution if
    02236         // if was previously froozen.
    02237         //
    02238
    02239         Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
    02240         OldCount = Thread->FreezeCount;
    02241         if (OldCount != 0) {
    02242             Thread->FreezeCount -= 1;
    02243
    02244             //
    02245             // If the resultant suspend count is zero and the freeze count is
    02246             // zero, then resume the thread by releasing its suspend semaphore.
    02247             //
    02248
    02249             if ((Thread->SuspendCount == 0) && (Thread->FreezeCount == 0)) {
    02250                 Thread->SuspendSemaphore.Header.SignalState += 1;
    02251                 KiWaitTest(&Thread->SuspendSemaphore, RESUME_INCREMENT);
    02252             }
    02253         }
    02254
    02255         NextEntry = NextEntry->Flink;
    02256     } while (NextEntry != ListHead);
    02257
    02258     //
    02259     // Unlock dispatcher database and lower IRQL to its previous
    02260     // value.
    02261     //
    02262
    02263     KiUnlockDispatcherDatabase(OldIrql);
    02264     KeLeaveCriticalRegion();
    02265     return;
    02266 }
    }

VOID KeThawExecution | ( | IN BOOLEAN | Enable | ) |

Definition at line 391 of file ke/debug.c.

References ClearMember, FREEZE_BACKUP, FrozenState, KeActiveProcessors, KeFindFirstSetRightMember, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), KiFreezeExecutionLock, KiFreezeFlag, KiFreezeLockBackup, KiOldIrql, KiProcessorBlock, KiRestoreInterrupts(), RUNNING, TARGET_FROZEN, and TARGET_THAW.

Referenced by KdExitDebugger().

    00397                    :
    00398
    00399     This function thaws the execution of all other processors in the host
    00400     configuration and then returns to the caller. It is intended for use by
    00401     the kernel debugger.
    00402
    00403 Arguments:
    00404
    00405     Enable - Supplies the previous interrupt enable that is to be restored
    00406         after having thawed the execution of all other processors.
    00407
    00408 Return Value:
    00409
    00410     None.
    00411
    00412 --*/
    00413
    00414 {
    00415 #if !defined(NT_UP)
    00416
    00417     KIRQL OldIrql;
    00418     ULONG TargetSet;
    00419     ULONG BitNumber;
    00420     ULONG Flag;
    00421     PKPRCB Prcb;
    00422
    00423     //
    00424     // Before releasing FreezeExecutionLock clear any all targets IpiFrozen
    00425     // flag.
    00426     //
    00427
    00428     KeGetCurrentPrcb()->IpiFrozen = RUNNING;
    00429
    00430     TargetSet = KeActiveProcessors & ~(1 << KeGetCurrentPrcb()->Number);
    00431     while (TargetSet != 0) {
    00432         BitNumber = KeFindFirstSetRightMember(TargetSet);
    00433         ClearMember(BitNumber, TargetSet);
    00434         Prcb = KiProcessorBlock[BitNumber];
    00435 #if IDBG
    00436         //
    00437         // If the target processor was not forzen, then don't wait
    00438         // for target to unfreeze.
    00439         //
    00440
    00441         if (FrozenState(Prcb->IpiFrozen) != TARGET_FROZEN) {
    00442             Prcb->IpiFrozen = RUNNING;
    00443             continue;
    00444         }
    00445 #endif
    00446
    00447         Prcb->IpiFrozen = TARGET_THAW;
    00448         while (Prcb->IpiFrozen == TARGET_THAW) {
    00449             KeYieldProcessor();
    00450         }
    00451     }
    00452
    00453     //
    00454     // Capture the previous IRQL before releasing the freeze lock.
    00455     //
    00456
    00457     OldIrql = KiOldIrql;
    00458
    00459 #if IDBG
    00460
    00461     Flag = KiFreezeFlag;
    00462     KiFreezeFlag = 0;
    00463
    00464     if ((Flag & FREEZE_BACKUP) != 0) {
    00465         KiReleaseSpinLock(&KiFreezeLockBackup);
    00466     } else {
    00467         KiReleaseSpinLock(&KiFreezeExecutionLock);
    00468     }
    00469
    00470 #else
    00471
    00472     KiFreezeFlag = 0;
    00473     KiReleaseSpinLock(&KiFreezeExecutionLock);
    00474
    00475 #endif
    00476 #endif  // !defined (NT_UP)
    00477
    00478
    00479     //
    00480     // Flush the current TB, instruction cache, and data cache.
    00481     //
    00482
    00483     KeFlushCurrentTb();
    00484     KeSweepCurrentIcache();
    00485     KeSweepCurrentDcache();
    00486
    00487     //
    00488     // Lower IRQL and restore interrupt enable
    00489     //
    00490
    00491 #if !defined(NT_UP)
    00492     KeLowerIrql(OldIrql);
    00493 #endif
    00494     KiRestoreInterrupts(Enable);
    00495     return;
    00496 }

BOOLEAN KeTryToAcquireSpinLock | ( | IN PKSPIN_LOCK | SpinLock,
|  | OUT PKIRQL | OldIrql
| ) |

| Referenced by MmTrimAllSystemPagableMemory().

NTKERNELAPI VOID KeUnstackDetachProcess | ( | IN PRKAPC_STATE | ApcState | ) |

Definition at line 512 of file procobj.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, _KTHREAD::ApcStatePointer, ASSERT, BALANCE_INCREMENT, DISPATCH_LEVEL, FALSE, _KEVENT::Header, KeBugCheck(), KeGetCurrentThread, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, KiLockDispatcherDatabase, KiMoveApcState(), KiProcessOutSwapListHead, KiRequestSoftwareInterrupt(), KiSwapEvent, KiSwapProcess(), KiUnlockDispatcherDatabase(), KiWaitTest(), NULL, _KAPC_STATE::Process, ProcessInTransition, _KTHREAD::SavedApcState, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, _KPROCESS::State, _KPROCESS::SwapListEntry, _KPROCESS::ThreadListHead, TRUE, UserMode, and _DISPATCHER_HEADER::WaitListHead.

Referenced by NtClose(), NtSetInformationObject(), NtWaitForMultipleObjects(), ObpCreateHandle(), ObpCreateUnnamedHandle(), and PspProcessDelete().

    00518                    :
    00519
    00520     This function detaches a thread from another process' address space
    00521     and restores previous attach state.
    00522
    00523 Arguments:
    00524
    00525     ApcState - Supplies a pointer to an APC state structure that was returned
    00526         from a previous call to stack attach process.
    00527
    00528 Return Value:
    00529
    00530     None.
    00531
    00532 --*/
    00533
    00534 {
    00535
    00536     KIRQL OldIrql;
    00537     PKPROCESS Process;
    00538     PKTHREAD Thread;
    00539
    00540     ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    00541
    00542     //
    00543     // Raise IRQL to dispatcher level and lock dispatcher database.
    00544     //
    00545
    00546     Thread = KeGetCurrentThread();
    00547     KiLockDispatcherDatabase(&OldIrql);
    00548
    00549     //
    00550     // If the APC state has a distinguished process pointer value, then no
    00551     // attach was performed on the paired call to stack attach process.
    00552     //
    00553
    00554     if (ApcState->Process != (PRKPROCESS)1) {
    00555
    00556         //
    00557         // If the current thread is not attached to another process, a kernel
    00558         // APC is in progress, or either the kernel or user mode APC queues
    00559         // are not empty, then call bug check.
    00560         //
    00561
    00562         if ((Thread->ApcStateIndex == 0) ||
    00563              (Thread->ApcState.KernelApcInProgress) ||
    00564              (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) ||
    00565              (IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE)) {
    00566             KeBugCheck(INVALID_PROCESS_DETACH_ATTEMPT);
    00567         }
    00568
    00569         //
    00570         // Unbias current process stack count and check if the process should
    00571         // be swapped out of memory.
    00572         //
    00573
    00574         Process = Thread->ApcState.Process;
    00575         Process->StackCount -= 1;
    00576         if ((Process->StackCount == 0) &&
    00577             (IsListEmpty(&Process->ThreadListHead) == FALSE)) {
    00578             Process->State = ProcessInTransition;
    00579             InsertTailList(&KiProcessOutSwapListHead, &Process->SwapListEntry);
    00580             KiSwapEvent.Header.SignalState = 1;
    00581             if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
    00582                 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
    00583             }
    00584         }
    00585
    00586         //
    00587         // Restore APC state and check whether the kernel APC queue contains
    00588         // an entry. If the kernel APC queue contains an entry then set kernel
    00589         // APC pending and request a software interrupt at APC_LEVEL.
    00590         //
    00591
    00592         if (ApcState->Process != NULL) {
    00593             KiMoveApcState(ApcState, &Thread->ApcState);
    00594
    00595         } else {
    00596             KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
    00597             Thread->SavedApcState.Process = (PKPROCESS)NULL;
    00598             Thread->ApcStatePointer[0] = &Thread->ApcState;
    00599             Thread->ApcStatePointer[1] = &Thread->SavedApcState;
    00600             Thread->ApcStateIndex = 0;
    00601         }
    00602
    00603         if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) {
    00604             Thread->ApcState.KernelApcPending = TRUE;
    00605             KiRequestSoftwareInterrupt(APC_LEVEL);
    00606         }
    00607
    00608         //
    00609         // Swap the address space back to the parent process.
    00610         //
    00611
    00612         KiSwapProcess(Thread->ApcState.Process, Process);
    00613     }
    00614
    00615     //
    00616     // Lower IRQL to its previous value and return.
    00617     //
    00618
    00619     KiUnlockDispatcherDatabase(OldIrql);
    00620     return;
    00621 }

NTKERNELAPI NTSTATUS KeUserModeCallback | ( | IN ULONG | ApiNumber,
|  | IN PVOID | InputBuffer,
|  | IN ULONG | InputLength,
|  | OUT PVOID * | OutputBuffer,
|  | OUT PULONG | OutputLength
| ) |

NTKERNELAPI NTSTATUS KeWaitForMultipleObjects | ( | IN ULONG | Count,
|  | IN PVOID | Object[],
|  | IN WAIT_TYPE | WaitType,
|  | IN KWAIT_REASON | WaitReason,
|  | IN KPROCESSOR_MODE | WaitMode,
|  | IN BOOLEAN | Alertable,
|  | IN PLARGE_INTEGER Timeout | OPTIONAL,
|  | IN PKWAIT_BLOCK WaitBlockArray | OPTIONAL
| ) |

Definition at line 395 of file wait.c.

References _KTHREAD::Alertable, APC_LEVEL, _KTHREAD::ApcState, ASSERT, Count, DISPATCH_LEVEL, _KTIMER::DueTime, ExRaiseStatus(), FALSE, _KMUTANT::Header, _KTIMER::Header, Index, KeBugCheck(), KeGetCurrentThread, _KAPC_STATE::KernelApcPending, KiActivateWaiterQueue(), KiAdjustQuantumThread(), KiComputeWaitInterval(), KiInsertTreeTimer(), KiInsertWaitList, KiLockDispatcherDatabase, KiSwapThread(), KiUnlockDispatcherDatabase(), KiWaitSatisfyAll(), KiWaitSatisfyMutant, KiWaitSatisfyOther, KWAIT_REASON, MutantObject, _KWAIT_BLOCK::NextWaitBlock, NTSTATUS(), NULL, _KWAIT_BLOCK::Object, _KMUTANT::OwnerThread, _KTHREAD::Queue, QueueObject, _DISPATCHER_HEADER::SignalState, _KTHREAD::State, TestForAlertPending, _KWAIT_BLOCK::Thread, THREAD_WAIT_OBJECTS, _KTHREAD::Timer, TIMER_WAIT_BLOCK, TRUE, _DISPATCHER_HEADER::Type, USHORT, _KTHREAD::WaitBlock, _KTHREAD::WaitBlockList, Waiting, _KTHREAD::WaitIrql, _KWAIT_BLOCK::WaitKey, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, _KTHREAD::WaitMode, _KTHREAD::WaitNext, _KTHREAD::WaitReason, _KTHREAD::WaitStatus, _KTHREAD::WaitTime, and _KWAIT_BLOCK::WaitType.

Referenced by CmpFileWrite(), ExpWorkerThreadBalanceManager(), InitiateWin32kCleanup(), KeBalanceSetManager(), MemPrintWriteThread(), MiDereferenceSegmentThread(), MiModifiedPageWriterWorker(), MmZeroPageThread(), NtWaitForMultipleObjects(), RawInputThread(), SmbTraceThreadEntry(), xxxMsgWaitForMultipleObjects(), xxxPollAndWaitForSingleObject(), and xxxSleepTask().

    00408                    :
    00409
    00410     This function waits until the specified objects attain a state of
    00411     Signaled. The wait can be specified to wait until all of the objects
    00412     attain a state of Signaled or until one of the objects attains a state
    00413     of Signaled. An optional timeout can also be specified. If a timeout
    00414     is not specified, then the wait will not be satisfied until the objects
    00415     attain a state of Signaled. If a timeout is specified, and the objects
    00416     have not attained a state of Signaled when the timeout expires, then
    00417     the wait is automatically satisfied. If an explicit timeout value of
    00418     zero is specified, then no wait will occur if the wait cannot be satisfied
    00419     immediately. The wait can also be specified as alertable.
    00420
    00421 Arguments:
    00422
    00423     Count - Supplies a count of the number of objects that are to be waited
    00424         on.
    00425
    00426     Object[] - Supplies an array of pointers to dispatcher objects.
    00427
    00428     WaitType - Supplies the type of wait to perform (WaitAll, WaitAny).
    00429
    00430     WaitReason - Supplies the reason for the wait.
    00431
    00432     WaitMode  - Supplies the processor mode in which the wait is to occur.
    00433
    00434     Alertable - Supplies a boolean value that specifies whether the wait is
    00435         alertable.
    00436
    00437     Timeout - Supplies a pointer to an optional absolute of relative time over
    00438         which the wait is to occur.
    00439
    00440     WaitBlockArray - Supplies an optional pointer to an array of wait blocks
    00441         that are to used to describe the wait operation.
    00442
    00443 Return Value:
    00444
    00445     The wait completion status. A value of STATUS_TIMEOUT is returned if a
    00446     timeout occurred. The index of the object (zero based) in the object
    00447     pointer array is returned if an object satisfied the wait. A value of
    00448     STATUS_ALERTED is returned if the wait was aborted to deliver an alert
    00449     to the current thread. A value of STATUS_USER_APC is returned if the
    00450     wait was aborted to deliver a user APC to the current thread.
    00451
    00452 --*/
    00453
    00454 {
    00455
    00456     LARGE_INTEGER DueTime;
    00457     ULONG Index;
    00458     LARGE_INTEGER NewTime;
    00459     PRKTHREAD NextThread;
    00460     PKMUTANT Objectx;
    00461     PLARGE_INTEGER OriginalTime;
    00462     PRKQUEUE Queue;
    00463     PRKTHREAD Thread;
    00464     PRKTIMER Timer;
    00465     PRKWAIT_BLOCK WaitBlock;
    00466     BOOLEAN WaitSatisfied;
    00467     NTSTATUS WaitStatus;
    00468     PKWAIT_BLOCK WaitTimer;
    00469
    00470     //
    00471     // If the dispatcher database lock is not already held, then set the wait
    00472     // IRQL and lock the dispatcher database. Else set boolean wait variable
    00473     // to FALSE.
    00474     //
    00475
    00476     Thread = KeGetCurrentThread();
    00477     if (Thread->WaitNext) {
    00478         Thread->WaitNext = FALSE;
    00479
    00480     } else {
    00481         KiLockDispatcherDatabase(&Thread->WaitIrql);
    00482     }
    00483
    00484     //
    00485     // If a wait block array has been specified, then the maximum number of
    00486     // objects that can be waited on is specified by MAXIMUM_WAIT_OBJECTS.
    00487     // Otherwise the builtin wait blocks in the thread object are used and
    00488     // the maximum number of objects that can be waited on is specified by
    00489     // THREAD_WAIT_OBJECTS. If the specified number of objects is not within
    00490     // limits, then bug check.
    00491     //
    00492
    00493     if (ARGUMENT_PRESENT(WaitBlockArray)) {
    00494         if (Count > MAXIMUM_WAIT_OBJECTS) {
    00495             KeBugCheck(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
    00496         }
    00497
    00498     } else {
    00499         if (Count > THREAD_WAIT_OBJECTS) {
    00500             KeBugCheck(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
    00501         }
    00502
    00503         WaitBlockArray = &Thread->WaitBlock[0];
    00504     }
    00505
    00506     //
    00507     // Start of wait loop.
    00508     //
    00509     // Note this loop is repeated if a kernel APC is delivered in the middle
    00510     // of the wait or a kernel APC is pending on the first attempt through
    00511     // the loop.
    00512     //
    00513
    00514     OriginalTime = Timeout;
    00515     do {
    00516
    00517         //
    00518         // Set address of wait block list in thread object.
    00519         //
    00520
    00521         Thread->WaitBlockList = WaitBlockArray;
    00522
    00523         //
    00524         // Test to determine if a kernel APC is pending.
    00525         //
    00526         // If a kernel APC is pending and the previous IRQL was less than
    00527         // APC_LEVEL, then a kernel APC was queued by another processor just
    00528         // after IRQL was raised to DISPATCH_LEVEL, but before the dispatcher
    00529         // database was locked.
    00530         //
    00531         // N.B. that this can only happen in a multiprocessor system.
    00532         //
    00533
    00534         if (Thread->ApcState.KernelApcPending && (Thread->WaitIrql < APC_LEVEL)) {
    00535
    00536             //
    00537             // Unlock the dispatcher database and lower IRQL to its previous
    00538             // value. An APC interrupt will immediately occur which will result
    00539             // in the delivery of the kernel APC if possible.
    00540             //
    00541
    00542             KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00543
    00544         } else {
    00545
    00546             //
    00547             // Construct wait blocks and check to determine if the wait is
    00548             // already satisfied. If the wait is satisfied, then perform
    00549             // wait completion and return. Else put current thread in a wait
    00550             // state if an explicit timeout value of zero is not specified.
    00551             //
    00552
    00553             Thread->WaitStatus = (NTSTATUS)0;
    00554             WaitSatisfied = TRUE;
    00555             for (Index = 0; Index < Count; Index += 1) {
    00556
    00557                 //
    00558                 // Test if wait can be satisfied immediately.
    00559                 //
    00560
    00561                 Objectx = (PKMUTANT)Object[Index];
    00562
    00563                 ASSERT(Objectx->Header.Type != QueueObject);
    00564
    00565                 if (WaitType == WaitAny) {
    00566
    00567                     //
    00568                     // If the object is a mutant object and the mutant object
    00569                     // has been recursively acquired MINLONG times, then raise
    00570                     // an exception. Otherwise if the signal state of the mutant
    00571                     // object is greater than zero, or the current thread is
    00572                     // the owner of the mutant object, then satisfy the wait.
    00573                     //
    00574
    00575                     if (Objectx->Header.Type == MutantObject) {
    00576                         if ((Objectx->Header.SignalState > 0) ||
    00577                             (Thread == Objectx->OwnerThread)) {
    00578                             if (Objectx->Header.SignalState != MINLONG) {
    00579                                 KiWaitSatisfyMutant(Objectx, Thread);
    00580                                 WaitStatus = (NTSTATUS)(Index | Thread->WaitStatus);
    00581                                 goto NoWait;
    00582
    00583                             } else {
    00584                                 KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00585                                 ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
    00586                             }
    00587                         }
    00588
    00589                     //
    00590                     // If the signal state is greater than zero, then satisfy
    00591                     // the wait.
    00592                     //
    00593
    00594                     } else if (Objectx->Header.SignalState > 0) {
    00595                         KiWaitSatisfyOther(Objectx);
    00596                         WaitStatus = (NTSTATUS)(Index);
    00597                         goto NoWait;
    00598                     }
    00599
    00600                 } else {
    00601
    00602                     //
    00603                     // If the object is a mutant object and the mutant object
    00604                     // has been recursively acquired MAXLONG times, then raise
    00605                     // an exception. Otherwise if the signal state of the mutant
    00606                     // object is less than or equal to zero and the current
    00607                     // thread is not the  owner of the mutant object, then the
    00608                     // wait cannot be satisfied.
    00609                     //
    00610
    00611                     if (Objectx->Header.Type == MutantObject) {
    00612                         if ((Thread == Objectx->OwnerThread) &&
    00613                             (Objectx->Header.SignalState == MINLONG)) {
    00614                             KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00615                             ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
    00616
    00617                         } else if ((Objectx->Header.SignalState <= 0) &&
    00618                                   (Thread != Objectx->OwnerThread)) {
    00619                             WaitSatisfied = FALSE;
    00620                         }
    00621
    00622                     //
    00623                     // If the signal state is less than or equal to zero, then
    00624                     // the wait cannot be satisfied.
    00625                     //
    00626
    00627                     } else if (Objectx->Header.SignalState <= 0) {
    00628                         WaitSatisfied = FALSE;
    00629                     }
    00630                 }
    00631
    00632                 //
    00633                 // Construct wait block for the current object.
    00634                 //
    00635
    00636                 WaitBlock = &WaitBlockArray[Index];
    00637                 WaitBlock->Object = (PVOID)Objectx;
    00638                 WaitBlock->WaitKey = (CSHORT)(Index);
    00639                 WaitBlock->WaitType = (USHORT)WaitType;
    00640                 WaitBlock->Thread = Thread;
    00641                 WaitBlock->NextWaitBlock = &WaitBlockArray[Index + 1];
    00642             }
    00643
    00644             //
    00645             // If the wait type is wait all, then check to determine if the
    00646             // wait can be satisfied immediately.
    00647             //
    00648
    00649             if ((WaitType == WaitAll) && (WaitSatisfied)) {
    00650                 WaitBlock->NextWaitBlock = &WaitBlockArray[0];
    00651                 KiWaitSatisfyAll(WaitBlock);
    00652                 WaitStatus = (NTSTATUS)Thread->WaitStatus;
    00653                 goto NoWait;
    00654             }
    00655
    00656             //
    00657             // Test for alert pending.
    00658             //
    00659
    00660             TestForAlertPending(Alertable);
    00661
    00662             //
    00663             // The wait cannot be satisifed immediately. Check to determine if
    00664             // a timeout value is specified.
    00665             //
    00666
    00667             if (ARGUMENT_PRESENT(Timeout)) {
    00668
    00669                 //
    00670                 // If the timeout value is zero, then return immediately without
    00671                 // waiting.
    00672                 //
    00673
    00674                 if (!(Timeout->LowPart | Timeout->HighPart)) {
    00675                     WaitStatus = (NTSTATUS)(STATUS_TIMEOUT);
    00676                     goto NoWait;
    00677                 }
    00678
    00679                 //
    00680                 // Initialize a wait block for the thread specific timer,
    00681                 // initialize timer wait list head, insert the timer in the
    00682                 // timer tree, and increment the number of wait objects.
    00683                 //
    00684                 // N.B. The timer wait block is initialized when the respective
    00685                 //      thread is initialized. Thus the constant fields are not
    00686                 //      reinitialized. These include the wait object, wait key,
    00687                 //      wait type, and the wait list entry link pointers.
    00688                 //
    00689
    00690                 WaitTimer = &Thread->WaitBlock[TIMER_WAIT_BLOCK];
    00691                 WaitBlock->NextWaitBlock = WaitTimer;
    00692                 WaitBlock = WaitTimer;
    00693                 Timer = &Thread->Timer;
    00694                 InitializeListHead(&Timer->Header.WaitListHead);
    00695                 if (KiInsertTreeTimer(Timer, *Timeout) == FALSE) {
    00696                     WaitStatus = (NTSTATUS)STATUS_TIMEOUT;
    00697                     goto NoWait;
    00698                 }
    00699
    00700                 DueTime.QuadPart = Timer->DueTime.QuadPart;
    00701             }
    00702
    00703             //
    00704             // Close up the circular list of wait control blocks.
    00705             //
    00706
    00707             WaitBlock->NextWaitBlock = &WaitBlockArray[0];
    00708
    00709             //
    00710             // Insert wait blocks in object wait lists.
    00711             //
    00712
    00713             WaitBlock = &WaitBlockArray[0];
    00714             do {
    00715                 Objectx = (PKMUTANT)WaitBlock->Object;
    00716                 InsertTailList(&Objectx->Header.WaitListHead, &WaitBlock->WaitListEntry);
    00717                 WaitBlock = WaitBlock->NextWaitBlock;
    00718             } while (WaitBlock != &WaitBlockArray[0]);
    00719
    00720             //
    00721             // If the current thread is processing a queue entry, then attempt
    00722             // to activate another thread that is blocked on the queue object.
    00723             //
    00724
    00725             Queue = Thread->Queue;
    00726             if (Queue != NULL) {
    00727                 KiActivateWaiterQueue(Queue);
    00728             }
    00729
    00730             //
    00731             // Set the thread wait parameters, set the thread dispatcher state
    00732             // to Waiting, and insert the thread in the wait list.
    00733             //
    00734
    00735             Thread->Alertable = Alertable;
    00736             Thread->WaitMode = WaitMode;
    00737             Thread->WaitReason = (UCHAR)WaitReason;
    00738             Thread->WaitTime= KiQueryLowTickCount();
    00739             Thread->State = Waiting;
    00740             KiInsertWaitList(WaitMode, Thread);
    00741
    00742             //
    00743             // Switch context to selected thread.
    00744             //
    00745             // Control is returned at the original IRQL.
    00746             //
    00747
    00748             ASSERT(Thread->WaitIrql <= DISPATCH_LEVEL);
    00749
    00750             WaitStatus = (NTSTATUS)KiSwapThread();
    00751
    00752             //
    00753             // If the thread was not awakened to deliver a kernel mode APC,
    00754             // then the wait status.
    00755             //
    00756
    00757             if (WaitStatus != STATUS_KERNEL_APC) {
    00758                 return WaitStatus;
    00759             }
    00760
    00761             if (ARGUMENT_PRESENT(Timeout)) {
    00762
    00763                 //
    00764                 // Reduce the amount of time remaining before timeout occurs.
    00765                 //
    00766
    00767                 Timeout = KiComputeWaitInterval(OriginalTime,
    00768                                                 &DueTime,
    00769                                                 &NewTime);
    00770             }
    00771         }
    00772
    00773         //
    00774         // Raise IRQL to DISPATCH_LEVEL and lock the dispatcher database.
    00775         //
    00776
    00777         KiLockDispatcherDatabase(&Thread->WaitIrql);
    00778     } while (TRUE);
    00779
    00780     //
    00781     // The thread is alerted or a user APC should be delivered. Unlock the
    00782     // dispatcher database, lower IRQL to its previous value, and return
    00783     // the wait status.
    00784     //
    00785
    00786     KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00787     return WaitStatus;
    00788
    00789     //
    00790     // The wait has been satisfied without actually waiting.
    00791     //
    00792     // If the thread priority that is less than time critical, then reduce
    00793     // the thread quantum. If a quantum end occurs, then reduce the thread
    00794     // priority.
    00795     //
    00796
    00797 NoWait:
    00798     KiAdjustQuantumThread(Thread);
    00799
    00800     //
    00801     // Unlock the dispatcher database, lower IRQL to its previous value, and
    00802     // return the wait status.
    00803     //
    00804
    00805     KiUnlockDispatcherDatabase(Thread->WaitIrql);
    00806     return WaitStatus;
    00807 }

NTKERNELAPI NTSTATUS KeWaitForSingleObject | ( | IN PVOID | Object,
|  | IN KWAIT_REASON | WaitReason,
|  | IN KPROCESSOR_MODE | WaitMode,
|  | IN BOOLEAN | Alertable,
|  | IN PLARGE_INTEGER Timeout | OPTIONAL
| ) |

Definition at line 163 of file cmwraper.c.

References _KTHREAD::Alertable, APC_LEVEL, _KTHREAD::ApcState, ASSERT, DISPATCH_LEVEL, _KTIMER::DueTime, ExRaiseStatus(), FALSE, _KMUTANT::Header, _KTIMER::Header, KeGetCurrentThread, _KAPC_STATE::KernelApcPending, KiActivateWaiterQueue(), KiAdjustQuantumThread(), KiComputeWaitInterval(), KiInsertTreeTimer(), KiInsertWaitList, KiLockDispatcherDatabase, KiSwapThread(), KiUnlockDispatcherDatabase(), KiWaitSatisfyMutant, KiWaitSatisfyOther, KiWaitSingleCallData, KWAIT_REASON, MutantObject, _KWAIT_BLOCK::NextWaitBlock, NTSTATUS(), NULL, _KWAIT_BLOCK::Object, _KMUTANT::OwnerThread, _KTHREAD::Queue, QueueObject, RECORD_CALL_DATA, _DISPATCHER_HEADER::SignalState, _KTHREAD::State, TestForAlertPending, _KTHREAD::Timer, TIMER_WAIT_BLOCK, TRUE, _DISPATCHER_HEADER::Type, _KTHREAD::WaitBlock, _KTHREAD::WaitBlockList, Waiting, _KTHREAD::WaitIrql, _KWAIT_BLOCK::WaitKey, _KWAIT_BLOCK::WaitListEntry, _DISPATCHER_HEADER::WaitListHead, _KTHREAD::WaitMode, _KTHREAD::WaitNext, _KTHREAD::WaitReason, _KTHREAD::WaitStatus, _KTHREAD::WaitTime, and _KWAIT_BLOCK::WaitType.

Referenced by CcCanIWrite(), CcInitializeCacheMap(), CcSetValidData(), CcWaitForCurrentLazyWriterActivity(), CcWaitOnActiveCount(), CcZeroData(), CmpFileRead(), CmpOpenHiveFiles(), DoResourceTest(), ExAllocatePool(), ExFreePool(), ExLockHandleTableEntry(), ExLockPool(), ExpGetProcessInformation(), ExpWaitForResource(), ExpWaitForResourceDdk(), ExUnregisterCallback(), FsRecGetDeviceSectors(), FsRecGetDeviceSectorSize(), FsRecLoadFileSystem(), FsRecReadBlock(), FsRtlBalanceReads(), FsRtlDeregisterUncProvider(), FsRtlGetFileSize(), FsRtlRegisterUncProvider(), FsRtlSetFileSize(), FsRtlSyncVolumes(), FsRtlWaitOnIrp(), GetDeviceChangeInfo(), HalpEnableAutomaticDriveLetterAssignment(), HalpGetFullGeometry(), HalpIsOldStyleFloppy(), HalpNextMountLetter(), HalpQueryDriveLayout(), HalpQueryPartitionType(), HalpSetMountLetter(), InitiateWin32kCleanup(), IoCancelFileOpen(), IoFreeDumpStack(), IoGetBootDiskInformation(), IoGetDmaAdapter(), IopAcquireFileObjectLock(), IopAllocateBootResources(), IopAllocateResources(), IopCancelAlertedRequest(), IopCloseFile(), IopCompleteDumpInitialization(), IopCompleteUnloadOrDelete(), IopCreateArcNames(), IopDeleteFile(), IopFilterResourceRequirementsCall(), IopGetDumpStack(), IopGetFileName(), IopGetSetObjectId(), IopGetSetSecurityObject(), IopGetVolumeId(), IopHardErrorThread(), IopHardwareProfileBeginTransition(), IopInvalidateVolumesForDevice(), IopLegacyResourceAllocation(), IopLoadFileSystemDriver(), IopLockMountedDeviceForRemove(), IopMountVolume(), IoPnPDeliverServicePowerNotification(), IopParseDevice(), IopProcessStartDevices(), IopProcessStartDevicesWorker(), IopQueryConflictList(), IopQueryRebalanceWorker(), IopQueryXxxInformation(), IopReallocateResources(), IopRebalance(), IopRequestHwProfileChangeNotification(), IopSendMessageToTrackService(), IopSetRemoteLink(), IopSynchronousApiServiceTail(), IopSynchronousCall(), IopSynchronousServiceTail(), IopUnlockMountedDeviceForRemove(), IopWaitForBootDevicesDeleted(), IopWaitForBootDevicesStarted(), IopWarmEjectDevice(), IoReleaseRemoveLockAndWaitEx(), IoReportTargetDeviceChange(), IoSetInformation(), IoShutdownSystem(), IoSynchronousInvalidateDeviceRelations(), IoVerifyVolume(), IovpInternalCompleteAfterWait(), IovpThrowBogusSynchronousIrp(), KeSetAutoAlignmentThread(), KeSwapProcessOrStack(), KiSetServerWaitClientEvent(), KiSuspendThread(), LfsCloseLogFile(), LfsFlushLbcb(), LfsWriteLogRecordIntoLogPage(), LpcpExtendPortZone(), LpcRequestWaitReplyPort(), MiCheckControlAreaStatus(), MiCheckForCrashDump(), MiCheckPageFilePath(), MiCheckPurgeAndUpMapCount(), MiCleanSection(), MiCreateImageFileMap(), MiDereferenceSession(), MiEmptyAllWorkingSets(), MiEnsureAvailablePageOrWait(), MiFlushSectionInternal(), MiGatherPagefilePages(), MiIssuePageExtendRequest(), MiLoadSystemImage(), MiLookupPsLoadedModule(), MiMakeOutswappedPageResident(), MiMapImageHeaderInHyperSpace(), MiMappedPageWriter(), MiModifiedPageWriterWorker(), MiWaitForInPageComplete(), MmAddVerifierThunks(), MmCleanProcessAddressSpace(), MmCreateSection(), MmGetVerifierInformation(), MmLockPagableSectionByHandle(), MmPurgeSection(), MmSetVerifierInformation(), MmShutdownSystem(), MmUnloadSystemImage(), NtDuplicateObject(), NtGetContextThread(), NtLoadDriver(), NtNotifyChangeMultipleKeys(), NtQueryInformationFile(), NtQueryInformationProcess(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtRequestWaitReplyPort(), NtSecureConnectPort(), NtSetContextThread(), NtSetInformationFile(), NtSetLdtEntries(), NtSignalAndWaitForSingleObject(), NtStartProfile(), NtStopProfile(), NtUnloadDriver(), NtWaitForSingleObject(), ObFindHandleForObject(), ObInitProcess(), ObKillProcess(), ObWaitForSingleObject(), PsLockProcess(), PspQueryDescriptorThread(), PspQueryLdtInformation(), PspSetLdtInformation(), PspSetLdtSize(), QueuePowerRequest(), RawInputThread(), RequestDeviceChange(), RtlReleaseRemoveLockAndWait(), RtlVolumeDeviceToDosName(), SmbTraceCompleteRdr(), SmbTraceCompleteSrv(), SmbTraceStart(), SmbTraceStop(), UdfAddVmcbMapping(), UdfPerformDevIoCtrl(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfReadSectors(), UdfRemoveVmcbMapping(), UdfVmcbLbnToVbn(), UdfVmcbVbnToLbn(), UdfWaitSync(), VdmDispatchStringIoToHandler(), VdmQueryDirectoryFile(), xHalExamineMBR(), xHalGetPartialGeometry(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), xHalIoWritePartitionTable(), xxxDesktopThread(), xxxInitInput(), xxxInitTerminal(), xxxRemoteDisconnect(), and xxxSleepThread().

    00170 {
    00171     return(STATUS_SUCCESS);
    00172 }

VOID FASTCALL KiSetPriorityThread | ( | IN PRKTHREAD | Thread,
|  | IN KPRIORITY | Priority
| ) |

Definition at line 576 of file thredsup.c.

References ASSERT, ClearMember, FALSE, KiDispatcherReadyListHead, KiFindReadyThread(), KiProcessorBlock, KiReadySummary, KiReadyThread(), KiRequestDispatchInterrupt, NULL, Ready, Running, SetMember, Standby, and _KTHREAD::State.

Referenced by ExpBoostOwnerThread(), KeDelayExecutionThread(), KeSetBasePriorityThread(), KeSetPriorityProcess(), KeSetPriorityThread(), KiAdjustQuantumThread(), and KiQuantumEnd().

    00583                    :
    00584
    00585     This function set the priority of the specified thread to the specified
    00586     value. If the thread is in the standby or running state, then the processor
    00587     may be redispatched. If the thread is in the ready state, then some other
    00588     thread may be preempted.
    00589
    00590 Arguments:
    00591
    00592     Thread - Supplies a pointer to a dispatcher object of type thread.
    00593
    00594     Priority - Supplies the new thread priority value.
    00595
    00596 Return Value:
    00597
    00598     None.
    00599
    00600 --*/
    00601
    00602 {
    00603
    00604     PRKPRCB Prcb;
    00605     ULONG Processor;
    00606     KPRIORITY ThreadPriority;
    00607     PRKTHREAD Thread1;
    00608
    00609     ASSERT(Priority <= HIGH_PRIORITY);
    00610
    00611     //
    00612     // Capture the current priority of the specified thread.
    00613     //
    00614
    00615     ThreadPriority = Thread->Priority;
    00616
    00617     //
    00618     // If the new priority is not equal to the old priority, then set the
    00619     // new priority of the thread and redispatch a processor if necessary.
    00620     //
    00621
    00622     if (Priority != ThreadPriority) {
    00623         Thread->Priority = (SCHAR)Priority;
    00624
    00625         //
    00626         // Case on the thread state.
    00627         //
    00628
    00629         switch (Thread->State) {
    00630
    00631             //
    00632             // Ready case - If the thread is not in the process ready queue,
    00633             // then remove it from its current dispatcher ready queue. If the
    00634             // new priority is less than the old priority, then insert the
    00635             // thread at the tail of the dispatcher ready queue selected by
    00636             // the new priority. Else reready the thread for execution.
    00637             //
    00638
    00639         case Ready:
    00640             if (Thread->ProcessReadyQueue == FALSE) {
    00641                 RemoveEntryList(&Thread->WaitListEntry);
    00642                 if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority])) {
    00643                     ClearMember(ThreadPriority, KiReadySummary);
    00644                 }
    00645
    00646                 if (Priority < ThreadPriority) {
    00647                     InsertTailList(&KiDispatcherReadyListHead[Priority],
    00648                                    &Thread->WaitListEntry);
    00649                     SetMember(Priority, KiReadySummary);
    00650
    00651                 } else {
    00652                     KiReadyThread(Thread);
    00653                 }
    00654             }
    00655
    00656             break;
    00657
    00658             //
    00659             // Standby case - If the thread's priority is being lowered, then
    00660             // attempt to find another thread to execute. If a new thread is
    00661             // found, then put the new thread in the standby state, and reready
    00662             // the old thread.
    00663             //
    00664
    00665         case Standby:
    00666
    00667 #if !defined(NT_UP)
    00668
    00669             Processor = Thread->NextProcessor;
    00670
    00671 #endif
    00672
    00673             if (Priority < ThreadPriority) {
    00674
    00675 #if !defined(NT_UP)
    00676
    00677                 Thread1 = KiFindReadyThread(Processor, Priority);
    00678
    00679 #else
    00680
    00681                 Thread1 = KiFindReadyThread(0, Priority);
    00682
    00683 #endif
    00684
    00685                 if (Thread1 != NULL) {
    00686
    00687 #if !defined(NT_UP)
    00688
    00689                     Prcb = KiProcessorBlock[Processor];
    00690
    00691 #else
    00692
    00693                     Prcb = KiProcessorBlock[0];
    00694
    00695 #endif
    00696
    00697                     Thread1->State = Standby;
    00698                     Prcb->NextThread = Thread1;
    00699                     KiReadyThread(Thread);
    00700                 }
    00701             }
    00702
    00703             break;
    00704
    00705             //
    00706             // Running case - If there is not a thread in the standby state
    00707             // on the thread's processor and the thread's priority is being
    00708             // lowered, then attempt to find another thread to execute. If
    00709             // a new thread is found, then put the new thread in the standby
    00710             // state, and request a redispatch on the thread's processor.
    00711             //
    00712
    00713         case Running:
    00714
    00715 #if !defined(NT_UP)
    00716
    00717             Processor = Thread->NextProcessor;
    00718             Prcb = KiProcessorBlock[Processor];
    00719
    00720 #else
    00721
    00722             Prcb = KiProcessorBlock[0];
    00723
    00724 #endif
    00725
    00726             if (Prcb->NextThread == NULL) {
    00727                 if (Priority < ThreadPriority) {
    00728
    00729 #if !defined(NT_UP)
    00730
    00731                     Thread1 = KiFindReadyThread(Processor, Priority);
    00732
    00733 #else
    00734
    00735                     Thread1 = KiFindReadyThread(0, Priority);
    00736
    00737 #endif
    00738
    00739                     if (Thread1 != NULL) {
    00740                         Thread1->State = Standby;
    00741                         Prcb->NextThread = Thread1;
    00742
    00743 #if !defined(NT_UP)
    00744
    00745                         KiRequestDispatchInterrupt(Processor);
    00746
    00747 #endif
    00748
    00749                     }
    00750                 }
    00751             }
    00752
    00753             break;
    00754
    00755             //
    00756             // Initialized, Terminated, Waiting, Transition case - For
    00757             // these states it is sufficient to just set the new thread
    00758             // priority.
    00759             //
    00760
    00761         default:
    00762             break;
    00763         }
    00764     }
    00765
    00766     return;
    00767 }

NTSTATUS KiSetServerWaitClientEvent | ( | IN PKEVENT | SeverEvent,
|  | IN PKEVENT | ClientEvent,
|  | IN ULONG | WaitMode
| ) |

Definition at line 1126 of file wait.c.

References EVENT_INCREMENT, FALSE, KeSetEvent(), KeWaitForSingleObject(), KPROCESSOR_MODE, NULL, TRUE, and WrEventPair.

    01134                    :
    01135
    01136     This function sets the specified server event and waits on specified
    01137     client event. The wait is performed such that an optimal switch to
    01138     the waiting thread occurs if possible. No timeout is associated with
    01139     the wait, and thus, the issuing thread will wait until the client event
    01140     is signaled or an APC is delivered.
    01141
    01142 Arguments:
    01143
    01144     ServerEvent - Supplies a pointer to a dispatcher object of type event.
    01145
    01146     ClientEvent - Supplies a pointer to a dispatcher object of type event.
    01147
    01148     WaitMode  - Supplies the processor mode in which the wait is to occur.
    01149
    01150 Return Value:
    01151
    01152     The wait completion status. A value of STATUS_SUCCESS is returned if
    01153     the specified object satisfied the wait. A value of STATUS_USER_APC is
    01154     returned if the wait was aborted to deliver a user APC to the current
    01155     thread.
    01156
    01157 --*/
    01158
    01159 {
    01160
    01161     //
    01162     // Set sever event and wait on client event atomically.
    01163     //
    01164
    01165     KeSetEvent(ServerEvent, EVENT_INCREMENT, TRUE);
    01166     return KeWaitForSingleObject(ClientEvent,
    01167                                  WrEventPair,
    01168                                  (KPROCESSOR_MODE)WaitMode,
    01169                                  FALSE,
    01170                                  NULL);
    01171 }

## Variable Documentation

KAFFINITY KeActiveProcessors

| Definition at line 2766 of file ke.h. Referenced by IoConnectInterrupt(), Ke386SetIoAccessMap(), KeBugCheckEx(), KeChangeColorPage(), KeDetachSessionSpace(), KeFlushEntireTb(), KeFlushIoBuffers(), KeFlushMultipleTb(), KeFlushMultipleTb64(), KeFlushSingleTb(), KeFlushSingleTb64(), KeFreezeExecution(), KeI386SetGdtSelector(), KeInitializeProfile(), KeInvalidateAllCaches(), KeQueryActiveProcessors(), KeSetSystemAffinityThread(), KeSetup80387OrEmulate(), KeSweepCacheRange(), KeSweepDcache(), KeSweepDcacheRange(), KeSweepIcache(), KeSweepIcacheRange(), KeSynchronizeMemoryAccess(), KeThawExecution(), KiCompleteEffectiveRangeChange(), KiFlushSingleTbSynchronous(), KiGetNewRid(), KiInitializeKernel(), KiInitializePAT(), KiInitMachineDependent(), KiIpiGenericCall(), KiIpiStallOnPacketTargets(), KiSyncNewRegionId(), MmCreatePeb(), NtQuerySystemInformation(), NtSetInformationJobObject(), NtSetInformationProcess(), and PspCreateProcess().

LARGE_INTEGER KeBootTime

| Definition at line 2767 of file ke.h. Referenced by IopCopyBootLogRegistryToFile(), KeSetSystemTime(), NtQuerySystemInformation(), and ViInjectResourceFailure().

ULONGLONG KeBootTimeBias

| Definition at line 2768 of file ke.h. Referenced by KeSetSystemTime(), and NtQuerySystemInformation().

LIST_ENTRY KeBugCheckCallbackListHead

| Definition at line 2770 of file ke.h. Referenced by KeRegisterBugCheckCallback(), KiInitSystem(), and KiScanBugCheckCallbackList().

KSPIN_LOCK KeBugCheckCallbackLock

| Definition at line 2771 of file ke.h. Referenced by KeDeregisterBugCheckCallback(), KeRegisterBugCheckCallback(), and KiInitSystem().

ULONG KeFeatureBits

| Definition at line 2780 of file ke.h. Referenced by KeI386VdmInitialize(), KeRestoreMtrr(), KeRestorePAT(), KeSetPhysicalCacheTypeRange(), KeSetup80387OrEmulate(), KiInitializeKernel(), KiInitializeMTRR(), KiInitializePAT(), KiInitMachineDependent(), KiLoadMTRR(), MiInitMachineDependent(), MmMapIoSpace(), and NtQuerySystemInformation().

PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch

| Definition at line 2772 of file ke.h. Referenced by KeUserModeCallback(), and PsEstablishWin32Callouts().

ULONGLONG KeInterruptTimeBias

| Definition at line 2769 of file ke.h. Referenced by KiCalibrateTimeAdjustment(), and NtQuerySystemInformation().

ULONG KeLicensedProcessors

| Definition at line 2789 of file ke.h.

PLOADER_PARAMETER_BLOCK KeLoaderBlock

| Definition at line 2773 of file ke.h. Referenced by CmpCreateHwProfileFriendlyName(), KeDumpMachineState(), KeStartAllProcessors(), KiInitializeAbios(), KiInitializeKernel(), KiInitializeMachineType(), and KiPcToFileHeader().

ULONG KeMaximumIncrement

| Definition at line 2774 of file ke.h. Referenced by ExpCopyProcessInfo(), ExpCopyThreadInfo(), KeQueryTimeIncrement(), KeSetTimeIncrement(), KeUpdateSystemTime(), KiCalibrateTimeAdjustment(), KiInitializeKernel(), NtQueryInformationJobObject(), NtQueryInformationProcess(), NtQueryInformationThread(), NtQuerySystemInformation(), NtSetInformationJobObject(), NtSetSystemInformation(), PsEnforceExecutionTimeLimits(), PspExitProcess(), PspFoldProcessAccountingIntoJob(), and VdmpDelayInterrupt().

ULONG KeMinimumIncrement

| Definition at line 2775 of file ke.h. Referenced by KeSetTimeIncrement(), and VdmpDelayInterrupt().

CCHAR KeNumberProcessors

| Definition at line 2776 of file ke.h. Referenced by CcInitializeCacheManager(), CmpConfigureProcessors(), CmpInitializeMachineDependentConfiguration(), ExpCheckForResource(), IoInitSystem(), IopInitializeDCB(), KdpGetContext(), KdpGetStateChange(), KdpReadControlSpace(), KdpReportLoadSymbolsStateChange(), KdpSetContext(), KdpSetStateChange(), KdpWriteControlSpace(), Ke386ConfigureCyrixProcessor(), KeConnectInterrupt(), KeFlushIoBuffers(), KeI386FlatToGdtSelector(), KeInitializeQueue(), KeInitializeThread(), KeSetIdealProcessorThread(), KeStartAllProcessors(), KeStartProfile(), KeSwitchFrozenProcessor(), KiAdjustInterruptTime(), KiInitializeKernel(), KiInitMachineDependent(), KiSynchronizeMTRRLoad(), KiSynchronizePATLoad(), KiTimerExpiration(), MmCreatePeb(), MmSetKernelDumpRange(), MmVerifyImageIsOkForMpUse(), NtQuerySystemInformation(), and ObInitSystem().

USHORT KeProcessorArchitecture

| Definition at line 2777 of file ke.h. Referenced by IopInitializeDCB(), KiInitializeKernel(), and NtQuerySystemInformation().

USHORT KeProcessorLevel

| Definition at line 2778 of file ke.h. Referenced by KdpPrintString(), KdpPromptString(), KdpReportLoadSymbolsStateChange(), KdpSetStateChange(), KiDisableAlignmentExceptions(), KiEnableAlignmentExceptions(), KiInitializeKernel(), MmDbgTranslatePhysicalAddress64(), and NtQuerySystemInformation().

USHORT KeProcessorRevision

| Definition at line 2779 of file ke.h. Referenced by KiInitializeKernel(), and NtQuerySystemInformation().

PVOID KeRaiseUserExceptionDispatcher

| Definition at line 2811 of file ke.h. Referenced by KeRaiseUserException(), and PspLookupKernelUserEntryPoints().

ULONG KeRegisteredProcessors

| Definition at line 2788 of file ke.h. Referenced by KeStartAllProcessors().

PULONG KeServiceCountTable

| Definition at line 2793 of file ke.h.

KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[NUMBER_SERVICE_TABLES]

| Definition at line 2794 of file ke.h. Referenced by KeAddSystemServiceTable(), KeInitializeThread(), KiInitSystem(), NtW32Call(), and PsConvertToGuiThread().

KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[NUMBER_SERVICE_TABLES]

| Definition at line 2795 of file ke.h. Referenced by KeAddSystemServiceTable(), KiInitSystem(), NtQuerySystemInformation(), and PsConvertToGuiThread().

KTHREAD_SWITCH_COUNTERS KeThreadSwitchCounters

| Definition at line 2784 of file ke.h. Referenced by NtQuerySystemInformation().

volatile KSYSTEM_TIME KeTickCount

| Definition at line 2797 of file ke.h. Referenced by IoCreateDriver(), KeUpdateSystemTime(), KiCalibrateTimeAdjustment(), and NtGetTickCount().

ULONG KeTimeAdjustment

| Definition at line 2812 of file ke.h. Referenced by KeSetTimeIncrement(), KeUpdateSystemTime(), NtQuerySystemInformation(), and NtSetSystemInformation().

ULONG KeTimeIncrement

| Definition at line 2813 of file ke.h. Referenced by KeSetTimeIncrement(), KiCalibrateTimeAdjustment(), NtQuerySystemInformation(), and VdmpDelayInterrupt().

BOOLEAN KeTimeSynchronization

| Definition at line 2814 of file ke.h. Referenced by NtQuerySystemInformation(), and NtSetSystemInformation().

PVOID KeUserApcDispatcher

| Definition at line 2808 of file ke.h. Referenced by KiInitializeUserApc(), and PspLookupKernelUserEntryPoints().

PVOID KeUserCallbackDispatcher

| Definition at line 2809 of file ke.h. Referenced by KdInitSystem(), KdpGetVersion(), KdUpdateDataBlock(), and PspLookupKernelUserEntryPoints().

PVOID KeUserExceptionDispatcher

| Definition at line 2810 of file ke.h. Referenced by KiDispatchException(), and PspLookupKernelUserEntryPoints().

CCHAR KiFindFirstSetRight[256]

| Definition at line 2781 of file ke.h.

PKPRCB KiProcessorBlock[]

| Definition at line 2782 of file ke.h. Referenced by CcInitializeCacheManager(), CmpInitializeMachineDependentConfiguration(), IoInitSystem(), KdpGetContext(), KdpGetStateChange(), KdpReadControlSpace(), KdpSetContext(), KdpWriteControlSpace(), KeFreezeExecution(), KeI386SetGdtSelector(), KeInsertQueueDpc(), KeSetAffinityThread(), KeStartAllProcessors(), KeSwitchFrozenProcessor(), KeThawExecution(), KiFlushForwardProgressTbBuffer(), KiInitializeKernel(), KiInitializePcr(), KiInvalidateForwardProgressTbBuffer(), KiIpiSend(), KiIpiSendPacket(), KiReadyThread(), KiSelectNextThread(), KiSetPriorityThread(), MmSetKernelDumpRange(), NtQuerySystemInformation(), and ObInitSystem().

ULONG KiStackProtectTime

| Definition at line 2783 of file ke.h. Referenced by KeBalanceSetManager(), KiOutSwapKernelStacks(), MiApplyDriverVerifier(), and MiVerifyingDriverUnloading().