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

ki.h File Reference

#include "ntos.h"
#include "stdio.h"
#include "stdlib.h"
#include "zwapi.h"

Go to the source code of this file.

Classes

struct  _KAPC_RECORD
struct  ADJUST_INTERRUPT_TIME_CONTEXT

Defines

#define ALERT_INCREMENT   2
#define BALANCE_INCREMENT   10
#define RESUME_INCREMENT   0
#define TIMER_EXPIRE_INCREMENT   0
#define TIME_CRITICAL_PRIORITY_BOUND   14
#define NIL   (PVOID)NULL
#define ClearMember(Member, Set)   Set = Set & (~(1 << (Member)))
#define SetMember(Member, Set)   Set = Set | (1 << (Member))
#define FindFirstSetLeftMember(Set, Member)
#define KiLockApcQueue(Thread, OldIrql)   *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&(Thread)->ApcQueueLock)
#define KiUnlockApcQueue(Thread, OldIrql)   KeReleaseSpinLock(&(Thread)->ApcQueueLock, (OldIrql))
#define KiLockContextSwap(OldIrql)   *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&KiContextSwapLock)
#define KiUnlockContextSwap(OldIrql)   KeReleaseSpinLock(&KiContextSwapLock, (OldIrql))
#define KiQueuedSpinLockContext(n)   (&(KeGetCurrentPrcb()->LockQueue[n]))
#define KiBoostPriorityThread(Thread, Increment)
#define KiInsertWaitList(_WaitMode, _Thread)
#define IPI_APC   1
#define IPI_DPC   2
#define IPI_FREEZE   4
#define IPI_PACKET_READY   8
#define IPI_SYNCH_REQUEST   0x10
#define IPI_INSTRUMENT_COUNT(a, b)
#define KiRemoveTreeTimer(Timer)
#define KiRequestApcInterrupt(Processor)
#define KiRequestDispatchInterrupt(Processor)
#define KiWaitSatisfyAny(_Object_, _Thread_)
#define KiWaitSatisfyMutant(_Object_, _Thread_)
#define KiWaitSatisfyOther(_Object_)
#define KiEnableAlignmentExceptions()
#define KiDisableAlignmentExceptions()

Typedefs

typedef _KAPC_RECORD KAPC_RECORD
typedef _KAPC_RECORDPKAPC_RECORD
typedef ULONG KIPI_REQUEST
typedef ULONG_PTR(* PKIPI_BROADCAST_WORKER )(IN ULONG_PTR Argument)
typedef * PADJUST_INTERRUPT_TIME_CONTEXT

Functions

VOID FASTCALL KiUnlockDispatcherDatabase (IN KIRQL OldIrql)
LOGICAL FASTCALL KiTryToAcquireQueuedSpinLock (IN PKSPIN_LOCK_QUEUE QueuedLock)
VOID ExpInitializeExecutive (IN ULONG Number, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN KiChannelInitialization (VOID)
VOID KiRundownChannel (VOID)
ULONG_PTR KiIpiGenericCall (IN PKIPI_BROADCAST_WORKER BroadcastFunction, IN ULONG_PTR Context)
VOID FASTCALL KiIpiSend (IN KAFFINITY TargetProcessors, IN KIPI_REQUEST Request)
VOID KiIpiSendPacket (IN KAFFINITY TargetProcessors, IN PKIPI_WORKER WorkerFunction, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
BOOLEAN KiIpiServiceRoutine (IN struct _KTRAP_FRAME *TrapFrame, IN struct _KEXCEPTION_FRAME *ExceptionFrame)
VOID FASTCALL KiIpiSignalPacketDone (IN PKIPI_CONTEXT SignalDone)
VOID KiIpiStallOnPacketTargets (KAFFINITY TargetSet)
VOID FASTCALL KiActivateWaiterQueue (IN PRKQUEUE Queue)
BOOLEAN KiAdjustInterruptTime (IN LONGLONG TimeDelta)
VOID KiApcInterrupt (VOID)
NTSTATUS KiCallUserMode (IN PVOID *OutputBuffer, IN PULONG OutputLength)
VOID KiCalibrateTimeAdjustment (PADJUST_INTERRUPT_TIME_CONTEXT Adjust)
VOID KiChainedDispatch (VOID)
LARGE_INTEGER KiComputeReciprocal (IN LONG Divisor, OUT PCCHAR Shift)
ULONG KiComputeTimerTableIndex (IN LARGE_INTEGER Interval, IN LARGE_INTEGER CurrentCount, IN PRKTIMER Timer)
PLARGE_INTEGER FASTCALL KiComputeWaitInterval (IN PLARGE_INTEGER OriginalTime, IN PLARGE_INTEGER DueTime, IN OUT PLARGE_INTEGER NewTime)
NTSTATUS KiContinue (IN PCONTEXT ContextRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
VOID KiDeliverApc (IN KPROCESSOR_MODE PreviousMode, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
BOOLEAN KiDisableInterrupts (VOID)
VOID KiRestoreInterrupts (IN BOOLEAN Enable)
VOID KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
KCONTINUE_STATUS KiSetDebugProcessor (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN KPROCESSOR_MODE PreviousMode)
ULONG KiCopyInformation (IN OUT PEXCEPTION_RECORD ExceptionRecord1, IN PEXCEPTION_RECORD ExceptionRecord2)
VOID KiDispatchInterrupt (VOID)
PKTHREAD FASTCALL KiFindReadyThread (IN ULONG Processor, KPRIORITY LowPriority)
VOID KiFloatingDispatch (VOID)
VOID FASTCALL KiFlushSingleTb (IN BOOLEAN Invalid, IN PVOID Virtual)
VOID KiFlushMultipleTb (IN BOOLEAN Invalid, IN PVOID *Virtual, IN ULONG Count)
PULONG KiGetUserModeStackAddress (VOID)
VOID KiInitializeContextThread (IN PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine OPTIONAL, IN PVOID StartContext OPTIONAL, IN PCONTEXT ContextFrame OPTIONAL)
VOID KiInitializeKernel (IN PKPROCESS Process, IN PKTHREAD Thread, IN PVOID IdleStack, IN PKPRCB Prcb, IN CCHAR Number, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID KiInitSystem (VOID)
BOOLEAN KiInitMachineDependent (VOID)
VOID KiInitializeUserApc (IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
LONG FASTCALL KiInsertQueue (IN PRKQUEUE Queue, IN PLIST_ENTRY Entry, IN BOOLEAN Head)
BOOLEAN FASTCALL KiInsertQueueApc (IN PKAPC Apc, IN KPRIORITY Increment)
LOGICAL FASTCALL KiInsertTreeTimer (IN PRKTIMER Timer, IN LARGE_INTEGER Interval)
VOID KiInterruptDispatch (VOID)
VOID KiInterruptDispatchRaise (IN PKINTERRUPT Interrupt)
VOID KiInterruptDispatchSame (IN PKINTERRUPT Interrupt)
KIRQL KiLockDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue)
VOID KiPassiveRelease (VOID)
NTSTATUS KiRaiseException (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN BOOLEAN FirstChance)
VOID FASTCALL KiReadyThread (IN PRKTHREAD Thread)
LOGICAL FASTCALL KiReinsertTreeTimer (IN PRKTIMER Timer, IN ULARGE_INTEGER DueTime)
PRKTHREAD FASTCALL KiSelectNextThread (IN PRKTHREAD Thread)
VOID KiSetSystemTime (IN PLARGE_INTEGER NewTime, OUT PLARGE_INTEGER OldTime)
VOID KiSuspendNop (IN struct _KAPC *Apc, IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PVOID *NormalContext, IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument2)
VOID KiSuspendThread (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
BOOLEAN KiSwapProcess (IN PKPROCESS NewProcess, IN PKPROCESS OldProcess)
LONG_PTR FASTCALL KiSwapThread (VOID)
VOID KiThreadStartup (IN PVOID StartContext)
VOID KiTimerExpiration (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID FASTCALL KiTimerListExpire (IN PLIST_ENTRY ExpiredListHead, IN KIRQL OldIrql)
VOID KiUnexpectedInterrupt (VOID)
VOID KiUnlockDeviceQueue (IN PKDEVICE_QUEUE DeviceQueue, IN KIRQL OldIrql)
VOID FASTCALL KiUnwaitThread (IN PRKTHREAD Thread, IN LONG_PTR WaitStatus, IN KPRIORITY Increment)
VOID KiUserApcDispatcher (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN PKNORMAL_ROUTINE NormalRoutine)
VOID KiUserExceptionDispatcher (IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextFrame)
VOID FASTCALL KiWaitSatisfyAll (IN PRKWAIT_BLOCK WaitBlock)
VOID FASTCALL KiWaitTest (IN PVOID Object, IN KPRIORITY Increment)
VOID KiFreezeTargetExecution (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KiPollFreezeExecution (VOID)
VOID KiSaveProcessorState (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KiSaveProcessorControlState (IN PKPROCESSOR_STATE ProcessorState)
VOID KiRestoreProcessorState (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KiRestoreProcessorControlState (IN PKPROCESSOR_STATE ProcessorState)
BOOLEAN KiTryToAcquireSpinLock (IN PKSPIN_LOCK SpinLock)

Variables

PRKTHREAD KiQuantumEnd (VOID)
ULONG KiDmaIoCoherency
ULONG KiMaximumDpcQueueDepth
ULONG KiMinimumDpcRate
ULONG KiAdjustDpcThreshold
KSPIN_LOCK KiContextSwapLock
PKDEBUG_ROUTINE KiDebugRoutine
PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine
KSPIN_LOCK KiDispatcherLock
LIST_ENTRY KiDispatcherReadyListHead [MAXIMUM_PRIORITY]
CCHAR KiFindFirstSetLeft [256]
CALL_PERFORMANCE_DATA KiFlushSingleCallData
ULONG_PTR KiHardwareTrigger
KAFFINITY KiIdleSummary
UCHAR KiFindLeftNibbleBitTable []
KEVENT KiSwapEvent
LIST_ENTRY KiProcessInSwapListHead
LIST_ENTRY KiProcessOutSwapListHead
LIST_ENTRY KiStackInSwapListHead
LIST_ENTRY KiProfileSourceListHead
BOOLEAN KiProfileAlignmentFixup
ULONG KiProfileAlignmentFixupInterval
ULONG KiProfileAlignmentFixupCount
ULONG KiProfileInterval
LIST_ENTRY KiProfileListHead
KSPIN_LOCK KiProfileLock
ULONG KiReadySummary
UCHAR KiArgumentTable []
ULONG KiServiceLimit
ULONG_PTR KiServiceTable []
CALL_PERFORMANCE_DATA KiSetEventCallData
ULONG KiTickOffset
LARGE_INTEGER KiTimeIncrementReciprocal
CCHAR KiTimeIncrementShiftCount
LIST_ENTRY KiTimerTableListHead [TIMER_TABLE_SIZE]
KAFFINITY KiTimeProcessor
KDPC KiTimerExpireDpc
KSPIN_LOCK KiFreezeExecutionLock
BOOLEAN KiSlavesStartExecution
PSWAP_CONTEXT_NOTIFY_ROUTINE KiSwapContextNotifyRoutine
PTHREAD_SELECT_NOTIFY_ROUTINE KiThreadSelectNotifyRoutine
PTIME_UPDATE_NOTIFY_ROUTINE KiTimeUpdateNotifyRoutine
LIST_ENTRY KiWaitInListHead
LIST_ENTRY KiWaitOutListHead
CALL_PERFORMANCE_DATA KiWaitSingleCallData
ULONG KiEnableTimerWatchdog
KSPIN_LOCK KiFreezeLockBackup
ULONG KiFreezeFlag
volatile ULONG KiSuspendState


Define Documentation

#define ALERT_INCREMENT   2
 

Definition at line 35 of file ki.h.

Referenced by KeAlertResumeThread(), and KeAlertThread().

#define BALANCE_INCREMENT   10
 

Definition at line 36 of file ki.h.

Referenced by KeDetachProcess(), KeTerminateThread(), KeUnstackDetachProcess(), KiAttachProcess(), and KiReadyThread().

#define ClearMember Member,
Set   )     Set = Set & (~(1 << (Member)))
 

Definition at line 58 of file ki.h.

Referenced by KeFreezeExecution(), KeI386SetGdtSelector(), KeSetAffinityThread(), KeThawExecution(), KiFindReadyThread(), KiFlushForwardProgressTbBuffer(), KiInvalidateForwardProgressTbBuffer(), KiReadyThread(), KiScanReadyQueues(), and KiSetPriorityThread().

#define FindFirstSetLeftMember Set,
Member   ) 
 

Value:

{ \ ULONG _Bit; \ ULONG _Mask; \ ULONG _Offset = 16; \ if ((_Mask = Set >> 16) == 0) { \ _Offset = 0; \ _Mask = Set; \ } \ if (_Mask >> 8) { \ _Offset += 8; \ } \ if ((_Bit = Set >> _Offset) & 0xf0) { \ _Bit >>= 4; \ _Offset += 4; \ } \ *(Member) = KiFindLeftNibbleBitTable[_Bit] + _Offset; \ }

Definition at line 68 of file ki.h.

Referenced by KiFindReadyThread(), and KiReadyThread().

#define IPI_APC   1
 

Definition at line 279 of file ki.h.

Referenced by KiIpiProcessRequests(), and main().

#define IPI_DPC   2
 

Definition at line 280 of file ki.h.

Referenced by KeInsertQueueDpc(), KiIpiProcessRequests(), KiReadyThread(), and main().

#define IPI_FREEZE   4
 

Definition at line 281 of file ki.h.

Referenced by KeBugCheckEx(), KeFreezeExecution(), KiIpiServiceRoutine(), KiPollFreezeExecution(), and main().

#define IPI_INSTRUMENT_COUNT a,
 ) 
 

Definition at line 303 of file ki.h.

Referenced by KeFlushEntireTb(), KeFlushMultipleTb(), KeFlushSingleTb(), KeSweepDcache(), KeSweepIcache(), KiFlushEntireTbTarget(), KiFlushIoBuffersTarget(), KiFlushMultipleTbTarget(), KiFlushSingleTbSynchronous(), KiFlushSingleTbTarget(), KiSweepDcacheTarget(), and KiSweepIcacheTarget().

#define IPI_PACKET_READY   8
 

Definition at line 282 of file ki.h.

Referenced by main().

#define IPI_SYNCH_REQUEST   0x10
 

Definition at line 283 of file ki.h.

#define KiBoostPriorityThread Thread,
Increment   ) 
 

Value:

{ \ KPRIORITY NewPriority; \ PKPROCESS Process; \ \ if ((Thread)->Priority < LOW_REALTIME_PRIORITY) { \ if ((Thread)->PriorityDecrement == 0) { \ NewPriority = (Thread)->BasePriority + (Increment); \ if (NewPriority > (Thread)->Priority) { \ if (NewPriority >= LOW_REALTIME_PRIORITY) { \ NewPriority = LOW_REALTIME_PRIORITY - 1; \ } \ \ Process = (Thread)->ApcState.Process; \ (Thread)->Quantum = Process->ThreadQuantum; \ KiSetPriorityThread((Thread), NewPriority); \ } \ } \ } \ }

Definition at line 179 of file ki.h.

Referenced by Ke386VdmInsertQueueApc(), and KeBoostPriorityThread().

 
#define KiDisableAlignmentExceptions  ) 
 

Definition at line 1095 of file ki.h.

Referenced by KeStopProfile(), KiInitializeKernel(), and KiStopProfileInterrupt().

 
#define KiEnableAlignmentExceptions  ) 
 

Definition at line 1094 of file ki.h.

Referenced by KeStartProfile(), and KiStartProfileInterrupt().

#define KiInsertWaitList _WaitMode,
_Thread   ) 
 

Value:

{ \ PLIST_ENTRY _ListHead; \ _ListHead = &KiWaitInListHead; \ if (((_WaitMode) == KernelMode) || \ ((_Thread)->EnableStackSwap == FALSE) || \ ((_Thread)->Priority >= (LOW_REALTIME_PRIORITY + 9))) { \ _ListHead = &KiWaitOutListHead; \ } \ InsertTailList(_ListHead, &(_Thread)->WaitListEntry); \ }

Definition at line 225 of file ki.h.

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeWaitForMultipleObjects(), and KeWaitForSingleObject().

#define KiLockApcQueue Thread,
OldIrql   )     *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&(Thread)->ApcQueueLock)
 

Definition at line 94 of file ki.h.

Referenced by KiDeliverApc().

#define KiLockContextSwap OldIrql   )     *(OldIrql) = KeAcquireSpinLockRaiseToSynch(&KiContextSwapLock)
 

Definition at line 128 of file ki.h.

Referenced by Ke386IoSetAccessProcess(), Ke386QueryIoAccessMap(), Ke386SetDescriptorProcess(), Ke386SetIoAccessMap(), Ke386SetLdtProcess(), Ke386SetVdmInterruptHandler(), KeFlushEntireTb(), KeFlushMultipleTb(), KeFlushMultipleTb64(), KeFlushSingleTb(), KeFlushSingleTb64(), KeIA32SetIoAccessMap(), KeInvalidateAllCaches(), KiAttachProcess(), KiCompleteEffectiveRangeChange(), KiFlushSingleTbSynchronous(), KiInitializePAT(), and PspReaper().

#define KiQueuedSpinLockContext n   )     (&(KeGetCurrentPrcb()->LockQueue[n]))
 

Definition at line 149 of file ki.h.

Referenced by KiInitializeKernel().

#define KiRemoveTreeTimer Timer   ) 
 

Value:

(Timer)->Header.Inserted = FALSE; \ RemoveEntryList(&(Timer)->TimerListEntry)

Definition at line 755 of file ki.h.

Referenced by KeCancelTimer(), KeSetSystemTime(), KeSetTimerEx(), KiInsertQueue(), KiInsertTimerTable(), KiTimerListExpire(), and KiUnwaitThread().

#define KiRequestApcInterrupt Processor   ) 
 

Value:

if (KeGetCurrentPrcb()->Number == (CCHAR)Processor) { \ KiRequestSoftwareInterrupt(APC_LEVEL); \ } else { \ KiIpiSend((KAFFINITY)(1 << Processor), IPI_APC); \ }

Definition at line 767 of file ki.h.

Referenced by KiInsertQueueApc().

#define KiRequestDispatchInterrupt Processor   ) 
 

Value:

if (KeGetCurrentPrcb()->Number != (CCHAR)Processor) { \ KiIpiSend((KAFFINITY)(1 << Processor), IPI_DPC); \ }

Definition at line 782 of file ki.h.

Referenced by KeSetAffinityThread(), KiReadyThread(), and KiSetPriorityThread().

#define KiUnlockApcQueue Thread,
OldIrql   )     KeReleaseSpinLock(&(Thread)->ApcQueueLock, (OldIrql))
 

Definition at line 101 of file ki.h.

Referenced by KiDeliverApc().

#define KiUnlockContextSwap OldIrql   )     KeReleaseSpinLock(&KiContextSwapLock, (OldIrql))
 

Definition at line 131 of file ki.h.

Referenced by Ke386IoSetAccessProcess(), Ke386QueryIoAccessMap(), Ke386SetDescriptorProcess(), Ke386SetIoAccessMap(), Ke386SetLdtProcess(), Ke386SetVdmInterruptHandler(), KeFlushEntireTb(), KeFlushMultipleTb(), KeFlushMultipleTb64(), KeFlushSingleTb(), KeFlushSingleTb64(), KeIA32SetIoAccessMap(), KeInvalidateAllCaches(), KiAttachProcess(), KiCompleteEffectiveRangeChange(), KiFlushSingleTbSynchronous(), KiInitializePAT(), and PspReaper().

#define KiWaitSatisfyAny _Object_,
_Thread_   ) 
 

Value:

{ \ if (((_Object_)->Header.Type & DISPATCHER_OBJECT_TYPE_MASK) == EventSynchronizationObject) { \ (_Object_)->Header.SignalState = 0; \ \ } else if ((_Object_)->Header.Type == SemaphoreObject) { \ (_Object_)->Header.SignalState -= 1; \ \ } else if ((_Object_)->Header.Type == MutantObject) { \ (_Object_)->Header.SignalState -= 1; \ if ((_Object_)->Header.SignalState == 0) { \ (_Thread_)->KernelApcDisable -= (_Object_)->ApcDisable; \ (_Object_)->OwnerThread = (_Thread_); \ if ((_Object_)->Abandoned == TRUE) { \ (_Object_)->Abandoned = FALSE; \ (_Thread_)->WaitStatus = STATUS_ABANDONED; \ } \ \ InsertHeadList((_Thread_)->MutantListHead.Blink, \ &(_Object_)->MutantListEntry); \ } \ } \ }

Definition at line 913 of file ki.h.

Referenced by KiWaitSatisfyAll(), and KiWaitTest().

#define KiWaitSatisfyMutant _Object_,
_Thread_   ) 
 

Value:

{ \ (_Object_)->Header.SignalState -= 1; \ if ((_Object_)->Header.SignalState == 0) { \ (_Thread_)->KernelApcDisable -= (_Object_)->ApcDisable; \ (_Object_)->OwnerThread = (_Thread_); \ if ((_Object_)->Abandoned == TRUE) { \ (_Object_)->Abandoned = FALSE; \ (_Thread_)->WaitStatus = STATUS_ABANDONED; \ } \ \ InsertHeadList((_Thread_)->MutantListHead.Blink, \ &(_Object_)->MutantListEntry); \ } \ }

Definition at line 960 of file ki.h.

Referenced by KeWaitForMultipleObjects(), and KeWaitForSingleObject().

#define KiWaitSatisfyOther _Object_   ) 
 

Value:

{ \ if (((_Object_)->Header.Type & DISPATCHER_OBJECT_TYPE_MASK) == EventSynchronizationObject) { \ (_Object_)->Header.SignalState = 0; \ \ } else if ((_Object_)->Header.Type == SemaphoreObject) { \ (_Object_)->Header.SignalState -= 1; \ \ } \ }

Definition at line 997 of file ki.h.

Referenced by KeWaitForMultipleObjects(), and KeWaitForSingleObject().

#define NIL   (PVOID)NULL
 

Definition at line 50 of file ki.h.

Referenced by KeInitializeApc(), KiInitializeKernel(), and KiInitSystem().

#define RESUME_INCREMENT   0
 

Definition at line 37 of file ki.h.

Referenced by KeAlertResumeThread(), KeForceResumeThread(), KeFreezeAllThreads(), KeResumeThread(), KeSuspendThread(), and KeThawAllThreads().

#define SetMember Member,
Set   )     Set = Set | (1 << (Member))
 

Definition at line 65 of file ki.h.

Referenced by KiInitializeKernel(), KiReadyThread(), KiSelectNextThread(), KiSetPriorityThread(), main(), and NtYieldExecution().

#define TIME_CRITICAL_PRIORITY_BOUND   14
 

Definition at line 44 of file ki.h.

Referenced by KiAdjustQuantumThread(), and KiUnwaitThread().

#define TIMER_EXPIRE_INCREMENT   0
 

Definition at line 38 of file ki.h.

Referenced by KeSetTimerEx(), and KiTimerListExpire().


Typedef Documentation

typedef struct _KAPC_RECORD KAPC_RECORD
 

Referenced by KiInitializeUserApc().

typedef ULONG KIPI_REQUEST
 

Definition at line 289 of file ki.h.

typedef * PADJUST_INTERRUPT_TIME_CONTEXT
 

typedef struct _KAPC_RECORD * PKAPC_RECORD
 

typedef ULONG_PTR(* PKIPI_BROADCAST_WORKER)(IN ULONG_PTR Argument)
 

Definition at line 293 of file ki.h.

Referenced by KiAdjustInterruptTime(), KiInitMachineDependent(), KiIpiGenericCall(), KiIpiGenericCallTarget(), KiSyncMC_Drain(), and KiSyncPrefetchVisible().


Function Documentation

VOID ExpInitializeExecutive IN ULONG  Number,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock
 

Referenced by KiInitializeKernel().

VOID FASTCALL KiActivateWaiterQueue IN PRKQUEUE  Queue  ) 
 

Definition at line 649 of file queueobj.c.

References KiUnwaitThread(), NULL, and _KWAIT_BLOCK::Thread.

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeTerminateThread(), KeWaitForMultipleObjects(), and KeWaitForSingleObject().

00655 : 00656 00657 This function is called when the current thread is about to enter a 00658 wait state and is currently processing a queue entry. The current 00659 number of threads processign entries for the queue is decrement and 00660 an attempt is made to activate another thread if the current count 00661 is less than the maximum count, there is a waiting thread, and the 00662 queue is not empty. 00663 00664 Arguments: 00665 00666 Queue - Supplies a pointer to a dispatcher object of type event. 00667 00668 Return Value: 00669 00670 None. 00671 00672 --*/ 00673 00674 { 00675 00676 PRLIST_ENTRY Entry; 00677 PRKTHREAD Thread; 00678 PRKWAIT_BLOCK WaitBlock; 00679 PRLIST_ENTRY WaitEntry; 00680 00681 // 00682 // Decrement the current count of active threads and check if another 00683 // thread can be activated. If the current number of active threads is 00684 // less than the target maximum number of threads, there is a entry in 00685 // in the queue, and a thread is waiting, then remove the entry from the 00686 // queue, decrement the number of entries in the queue, and unwait the 00687 // respectiive thread. 00688 // 00689 00690 Queue->CurrentCount -= 1; 00691 if (Queue->CurrentCount < Queue->MaximumCount) { 00692 Entry = Queue->EntryListHead.Flink; 00693 WaitEntry = Queue->Header.WaitListHead.Blink; 00694 if ((Entry != &Queue->EntryListHead) && 00695 (WaitEntry != &Queue->Header.WaitListHead)) { 00696 RemoveEntryList(Entry); 00697 Entry->Flink = NULL; 00698 Queue->Header.SignalState -= 1; 00699 WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry); 00700 Thread = WaitBlock->Thread; 00701 KiUnwaitThread(Thread, (LONG_PTR)Entry, 0); 00702 } 00703 } 00704 00705 return; 00706 }

BOOLEAN KiAdjustInterruptTime IN LONGLONG  TimeDelta  ) 
 

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

References ADJUST_INTERRUPT_TIME_CONTEXT::Adjustment, ADJUST_INTERRUPT_TIME_CONTEXT::Barrier, FALSE, ADJUST_INTERRUPT_TIME_CONTEXT::HalNumber, KeNumberProcessors, KiCalibrateTimeAdjustment(), KiIpiGenericCall(), ADJUST_INTERRUPT_TIME_CONTEXT::KiNumber, PKIPI_BROADCAST_WORKER, and TRUE.

Referenced by KeSetSystemTime(), and KeStartAllProcessors().

00549 : 00550 00551 This function moves the physical interrupt time of the system 00552 foreward by TimeDelta after a system wake has occurred. 00553 00554 Arguments: 00555 00556 TimeDelta - amount of time to bump foreward interrupt time, tick 00557 count and the perforamnce counter in 100ns units 00558 00559 Return Value: 00560 00561 None. 00562 00563 --*/ 00564 { 00565 ADJUST_INTERRUPT_TIME_CONTEXT Adjust; 00566 00567 // 00568 // Can only move time foreward 00569 // 00570 00571 if (TimeDelta < 0) { 00572 00573 return FALSE; 00574 00575 } else { 00576 00577 Adjust.KiNumber = KeNumberProcessors; 00578 Adjust.HalNumber = KeNumberProcessors; 00579 Adjust.Adjustment = (ULONGLONG) TimeDelta; 00580 Adjust.Barrier = 1; 00581 00582 KiIpiGenericCall ( 00583 (PKIPI_BROADCAST_WORKER) KiCalibrateTimeAdjustment, 00584 (ULONG_PTR)(&Adjust) 00585 ); 00586 00587 return TRUE; 00588 } 00589 }

VOID KiApcInterrupt VOID   ) 
 

Referenced by KiInitializeKernel().

VOID KiCalibrateTimeAdjustment PADJUST_INTERRUPT_TIME_CONTEXT  Adjust  ) 
 

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

References HalCalibratePerformanceCounter(), KeInsertQueueDpc(), KeInterruptTimeBias, KeMaximumIncrement, KeQueryInterruptTime(), KeQueryPerformanceCounter(), KeRemoveQueueDpc(), KeTickCount, KeTimeIncrement, KiDisableInterrupts(), KiPollFreezeExecution(), KiRestoreInterrupts(), KiTickOffset, KiTimerExpireDpc, NULL, RtlExtendedLargeIntegerDivide(), and TIMER_TABLE_SIZE.

Referenced by KiAdjustInterruptTime().

00597 : 00598 00599 Worker function for KiAdjustInterruptTime to calibrate the 00600 adjustment of time on all processors. 00601 00602 Arguments: 00603 00604 Adjust - context structure for operation 00605 00606 Return Value: 00607 00608 None. 00609 00610 --*/ 00611 { 00612 BOOLEAN Enable; 00613 LARGE_INTEGER InterruptTime; 00614 LARGE_INTEGER SetTime; 00615 LARGE_INTEGER PerfFreq; 00616 ULARGE_INTEGER li; 00617 LARGE_INTEGER NewTickCount; 00618 ULONG NewTickOffset; 00619 ULONG cl, divisor; 00620 00621 // 00622 // As each processor arrives, subtract one off the remaining processor 00623 // count. If this is the last processor to arrive compute the time 00624 // change, and signal all processor when to applied the performance 00625 // counter change. 00626 // 00627 00628 if (InterlockedDecrement((PLONG) &Adjust->KiNumber)) { 00629 00630 Enable = KiDisableInterrupts(); 00631 00632 // 00633 // It is possible to deadlock here if one or more of the 00634 // other processors gets and processes a freeze request 00635 // while this processor has interrupts disabled. Poll 00636 // for IPI_FREEZE requests until all processors are known 00637 // to be in this code and hence wont be requesting a 00638 // freeze. 00639 // 00640 00641 do { 00642 KiPollFreezeExecution(); 00643 } while (Adjust->KiNumber != (ULONG)-1); 00644 00645 // 00646 // Wait to perform the time set 00647 // 00648 00649 while (Adjust->Barrier) ; 00650 00651 } else { 00652 00653 // 00654 // Set timer expiration dpc to scan the timer queues once 00655 // for any expired timers 00656 // 00657 00658 KeRemoveQueueDpc (&KiTimerExpireDpc); 00659 KeInsertQueueDpc (&KiTimerExpireDpc, (PVOID) TIMER_TABLE_SIZE, NULL); 00660 00661 // 00662 // Disable interrupts and indicate that this processor is now 00663 // in final portion of this code. 00664 // 00665 00666 Enable = KiDisableInterrupts(); 00667 InterlockedDecrement((PLONG) &Adjust->KiNumber); 00668 00669 // 00670 // Get the current times 00671 // 00672 00673 KeQueryPerformanceCounter (&PerfFreq); 00674 InterruptTime.QuadPart = KeQueryInterruptTime() + Adjust->Adjustment; 00675 SetTime.QuadPart = InterruptTime.QuadPart + KeTimeIncrement / 2; 00676 00677 // 00678 // Compute performance counter for current SetTime 00679 // 00680 00681 // 00682 // Multiply SetTime * PerfCount and obtain 96bit result 00683 // in cl, li.LowPart, li.HighPart. Then divide the 96bit 00684 // result by 10,000,000 to get new performance counter value. 00685 // 00686 00687 li.QuadPart = RtlEnlargedUnsignedMultiply ( 00688 (ULONG) SetTime.LowPart, 00689 (ULONG) PerfFreq.LowPart 00690 ).QuadPart; 00691 00692 cl = li.LowPart; 00693 li.QuadPart = li.HighPart + 00694 RtlEnlargedUnsignedMultiply ( 00695 (ULONG) SetTime.LowPart, 00696 (ULONG) PerfFreq.HighPart 00697 ).QuadPart; 00698 00699 li.QuadPart = li.QuadPart + 00700 RtlEnlargedUnsignedMultiply ( 00701 (ULONG) SetTime.HighPart, 00702 (ULONG) PerfFreq.LowPart 00703 ).QuadPart; 00704 00705 li.HighPart = li.HighPart + SetTime.HighPart * PerfFreq.HighPart; 00706 00707 divisor = 10000000; 00708 Adjust->NewCount.HighPart = 00709 RtlEnlargedUnsignedDivide ( 00710 li, 00711 divisor, 00712 &li.HighPart 00713 ); 00714 00715 li.LowPart = cl; 00716 Adjust->NewCount.LowPart = 00717 RtlEnlargedUnsignedDivide ( 00718 li, 00719 divisor, 00720 NULL 00721 ); 00722 00723 // 00724 // Compute tick count and tick offset for current InterruptTime 00725 // 00726 00727 NewTickCount = RtlExtendedLargeIntegerDivide( 00728 InterruptTime, 00729 KeMaximumIncrement, 00730 &NewTickOffset 00731 ); 00732 00733 // 00734 // Apply changes to InterruptTime, TickCount, TickOffset, and the 00735 // performance counter 00736 // 00737 00738 KiTickOffset = KeMaximumIncrement - NewTickOffset; 00739 KeInterruptTimeBias += Adjust->Adjustment; 00740 SharedUserData->TickCountLow = NewTickCount.LowPart; 00741 00742 #if defined(_WIN64) 00743 00744 KeTickCount = NewTickCount.QuadPart; 00745 SharedUserData->InterruptHigh2Time = InterruptTime.HighPart; 00746 SharedUserData->InterruptTime = InterruptTime.QuadPart; 00747 00748 #elif defined(ALPHA) 00749 00750 KeTickCount = NewTickCount.QuadPart; 00751 SharedUserData->InterruptTime = InterruptTime.QuadPart; 00752 00753 #else 00754 KeTickCount.High2Time = NewTickCount.HighPart; 00755 KeTickCount.LowPart = NewTickCount.LowPart; 00756 KeTickCount.High1Time = NewTickCount.HighPart; 00757 00758 SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart; 00759 SharedUserData->InterruptTime.LowPart = InterruptTime.LowPart; 00760 SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart; 00761 #endif 00762 00763 // 00764 // Apply the performance counter change 00765 // 00766 00767 Adjust->Barrier = 0; 00768 } 00769 00770 HalCalibratePerformanceCounter ( 00771 (volatile PLONG) &Adjust->HalNumber, 00772 (ULONGLONG) Adjust->NewCount.QuadPart 00773 ); 00774 00775 KiRestoreInterrupts(Enable); 00776 }

NTSTATUS KiCallUserMode IN PVOID *  OutputBuffer,
IN PULONG  OutputLength
 

Referenced by KdpGetVersion(), and KeUserModeCallback().

VOID KiChainedDispatch VOID   ) 
 

Referenced by KeConnectInterrupt(), KeDisconnectInterrupt(), and KiGetVectorInfo().

BOOLEAN KiChannelInitialization VOID   ) 
 

Referenced by KeInitSystem().

LARGE_INTEGER KiComputeReciprocal IN LONG  Divisor,
OUT PCCHAR  Shift
 

Definition at line 237 of file kiinit.c.

Referenced by KiInitializeKernel().

00244 : 00245 00246 This function computes the large integer reciprocal of the specified 00247 value. 00248 00249 Arguments: 00250 00251 Divisor - Supplies the value for which the large integer reciprocal is 00252 computed. 00253 00254 Shift - Supplies a pointer to a variable that receives the computed 00255 shift count. 00256 00257 Return Value: 00258 00259 The large integer reciprocal is returned as the fucntion value. 00260 00261 --*/ 00262 00263 { 00264 00265 LARGE_INTEGER Fraction; 00266 LONG NumberBits; 00267 LONG Remainder; 00268 00269 // 00270 // Compute the large integer reciprocal of the specified value. 00271 // 00272 00273 NumberBits = 0; 00274 Remainder = 1; 00275 Fraction.LowPart = 0; 00276 Fraction.HighPart = 0; 00277 while (Fraction.HighPart >= 0) { 00278 NumberBits += 1; 00279 Fraction.HighPart = (Fraction.HighPart << 1) | (Fraction.LowPart >> 31); 00280 Fraction.LowPart <<= 1; 00281 Remainder <<= 1; 00282 if (Remainder >= Divisor) { 00283 Remainder -= Divisor; 00284 Fraction.LowPart |= 1; 00285 } 00286 } 00287 00288 if (Remainder != 0) { 00289 if ((Fraction.LowPart == 0xffffffff) && (Fraction.HighPart == 0xffffffff)) { 00290 Fraction.LowPart = 0; 00291 Fraction.HighPart = 0x80000000; 00292 NumberBits -= 1; 00293 00294 } else { 00295 if (Fraction.LowPart == 0xffffffff) { 00296 Fraction.LowPart = 0; 00297 Fraction.HighPart += 1; 00298 00299 } else { 00300 Fraction.LowPart += 1; 00301 } 00302 } 00303 } 00304 00305 // 00306 // Compute the shift count value and return the reciprocal fraction. 00307 // 00308 00309 *Shift = (CCHAR)(NumberBits - 64); 00310 return Fraction; 00311 } }

ULONG KiComputeTimerTableIndex IN LARGE_INTEGER  Interval,
IN LARGE_INTEGER  CurrentCount,
IN PRKTIMER  Timer
 

Referenced by KiInsertTimerTable().

PLARGE_INTEGER FASTCALL KiComputeWaitInterval IN PLARGE_INTEGER  OriginalTime,
IN PLARGE_INTEGER  DueTime,
IN OUT PLARGE_INTEGER  NewTime
 

Definition at line 1175 of file wait.c.

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeWaitForMultipleObjects(), and KeWaitForSingleObject().

01183 : 01184 01185 This function recomputes the wait interval after a thread has been 01186 awakened to deliver a kernel APC. 01187 01188 Arguments: 01189 01190 OriginalTime - Supplies a pointer to the original timeout value. 01191 01192 DueTime - Supplies a pointer to the previous due time. 01193 01194 NewTime - Supplies a pointer to a variable that receives the 01195 recomputed wait interval. 01196 01197 Return Value: 01198 01199 A pointer to the new time is returned as the function value. 01200 01201 --*/ 01202 01203 { 01204 01205 // 01206 // If the original wait time was absolute, then return the same 01207 // absolute time. Otherwise, reduce the wait time remaining before 01208 // the time delay expires. 01209 // 01210 01211 if (OriginalTime->QuadPart >= 0) { 01212 return OriginalTime; 01213 01214 } else { 01215 KiQueryInterruptTime(NewTime); 01216 NewTime->QuadPart -= DueTime->QuadPart; 01217 return NewTime; 01218 } 01219 } }

NTSTATUS KiContinue IN PCONTEXT  ContextRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame
 

Definition at line 99 of file raisexcp.c.

References APC_LEVEL, EXCEPTION_EXECUTE_HANDLER, FALSE, KeContextToKframes(), KeLowerIrql(), KeRaiseIrql(), KernelMode, KiContinuePreviousModeUser(), KPROCESSOR_MODE, NTSTATUS(), Status, and TRUE.

00107 : 00108 00109 This function is called to copy the specified context frame to the 00110 specified exception and trap frames for the continue system service. 00111 00112 Arguments: 00113 00114 ContextRecord - Supplies a pointer to a context record. 00115 00116 ExceptionFrame - Supplies a pointer to an exception frame. 00117 00118 TrapFrame - Supplies a pointer to a trap frame. 00119 00120 Return Value: 00121 00122 STATUS_ACCESS_VIOLATION is returned if the context record is not readable 00123 from user mode. 00124 00125 STATUS_DATATYPE_MISALIGNMENT is returned if the context record is not 00126 properly aligned. 00127 00128 STATUS_SUCCESS is returned if the context frame is copied successfully 00129 to the specified exception and trap frames. 00130 00131 --*/ 00132 00133 { 00134 KPROCESSOR_MODE PreviousMode; 00135 NTSTATUS Status; 00136 KIRQL OldIrql; 00137 BOOLEAN IrqlChanged = FALSE; 00138 00139 // 00140 // Synchronize with other context operations. 00141 // 00142 00143 Status = STATUS_SUCCESS; 00144 if (KeGetCurrentIrql() < APC_LEVEL) { 00145 00146 // 00147 // To support try-except and ExRaiseStatus in device driver code we 00148 // need to check if we are already at raised level. 00149 // 00150 00151 IrqlChanged = TRUE; 00152 KeRaiseIrql(APC_LEVEL, &OldIrql); 00153 } 00154 00155 // 00156 // Establish an exception handler and probe and capture the specified 00157 // context record if the previous mode is user. If the probe or copy 00158 // fails, then return the exception code as the function value. Else 00159 // copy the context record to the specified exception and trap frames, 00160 // and return success as the function value. 00161 // 00162 00163 try { 00164 00165 // 00166 // Get the previous processor mode. If the previous processor mode is 00167 // user, then probe and copy the specified context record. 00168 // 00169 00170 PreviousMode = KeGetPreviousMode(); 00171 if (PreviousMode != KernelMode) { 00172 KiContinuePreviousModeUser(ContextRecord, 00173 ExceptionFrame, 00174 TrapFrame, 00175 PreviousMode); 00176 } else { 00177 00178 // 00179 // Move information from the context record to the exception 00180 // and trap frames. 00181 // 00182 00183 KeContextToKframes(TrapFrame, 00184 ExceptionFrame, 00185 ContextRecord, 00186 ContextRecord->ContextFlags, 00187 PreviousMode); 00188 } 00189 00190 // 00191 // If an exception occurs during the probe or copy of the context 00192 // record, then always handle the exception and return the exception 00193 // code as the status value. 00194 // 00195 00196 } except(EXCEPTION_EXECUTE_HANDLER) { 00197 Status = GetExceptionCode(); 00198 } 00199 00200 if (IrqlChanged) { 00201 KeLowerIrql (OldIrql); 00202 } 00203 00204 return Status; 00205 }

ULONG KiCopyInformation IN OUT PEXCEPTION_RECORD  ExceptionRecord1,
IN PEXCEPTION_RECORD  ExceptionRecord2
 

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

References EXCEPTION_EXECUTE_HANDLER.

Referenced by Ki386CheckDelayedNpxTrap(), KiDispatchException(), KiEmulateByteWord(), KiEmulateDcbz(), KiEmulateFloating(), KiEmulateReference(), and KiInitializeUserApc().

00991 : 00992 00993 This function is called from an exception filter to copy the exception 00994 information from one exception record to another when an exception occurs. 00995 00996 Arguments: 00997 00998 ExceptionRecord1 - Supplies a pointer to the destination exception record. 00999 01000 ExceptionRecord2 - Supplies a pointer to the source exception record. 01001 01002 Return Value: 01003 01004 A value of EXCEPTION_EXECUTE_HANDLER is returned as the function value. 01005 01006 --*/ 01007 01008 { 01009 01010 // 01011 // Copy one exception record to another and return value that causes 01012 // an exception handler to be executed. 01013 // 01014 01015 RtlMoveMemory((PVOID)ExceptionRecord1, 01016 (PVOID)ExceptionRecord2, 01017 sizeof(EXCEPTION_RECORD)); 01018 01019 return EXCEPTION_EXECUTE_HANDLER; 01020 }

VOID KiDeliverApc IN KPROCESSOR_MODE  PreviousMode,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame
 

Definition at line 30 of file apcsup.c.

References APC_LEVEL, _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, FALSE, _KAPC::Inserted, KeBugCheckEx(), KeGetCurrentThread, KeLowerIrql(), KeRaiseIrql(), _KTHREAD::KernelApcDisable, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, _KAPC::KernelRoutine, KeTestAlertThread(), KiInitializeUserApc(), KiLockApcQueue, KiUnlockApcQueue, _KAPC::NormalContext, _KAPC::NormalRoutine, NULL, PKKERNEL_ROUTINE, PKNORMAL_ROUTINE, _KAPC::SystemArgument1, _KAPC::SystemArgument2, TRUE, _KAPC_STATE::UserApcPending, and UserMode.

Referenced by KiDispatchSoftwareInterrupt().

00038 : 00039 00040 This function is called from the APC interrupt code and when one or 00041 more of the APC pending flags are set at system exit and the previous 00042 IRQL is zero. All special kernel APC's are delivered first, followed 00043 by normal kernel APC's if one is not already in progress, and finally 00044 if the user APC queue is not empty, the user APC pending flag is set, 00045 and the previous mode is user, then a user APC is delivered. On entry 00046 to this routine IRQL is set to APC_LEVEL. 00047 00048 N.B. The exception frame and trap frame addresses are only guaranteed 00049 to be valid if, and only if, the previous mode is user. 00050 00051 Arguments: 00052 00053 PreviousMode - Supplies the previous processor mode. 00054 00055 ExceptionFrame - Supplies a pointer to an exception frame. 00056 00057 TrapFrame - Supplies a pointer to a trap frame. 00058 00059 Return Value: 00060 00061 None. 00062 00063 --*/ 00064 00065 { 00066 00067 PKAPC Apc; 00068 PKKERNEL_ROUTINE KernelRoutine; 00069 PLIST_ENTRY NextEntry; 00070 PVOID NormalContext; 00071 PKNORMAL_ROUTINE NormalRoutine; 00072 KIRQL OldIrql; 00073 PVOID SystemArgument1; 00074 PVOID SystemArgument2; 00075 PKTHREAD Thread; 00076 00077 // 00078 // Raise IRQL to dispatcher level and lock the APC queue. 00079 // 00080 00081 Thread = KeGetCurrentThread(); 00082 KiLockApcQueue(Thread, &OldIrql); 00083 00084 // 00085 // Get address of current thread object, clear kernel APC pending, and 00086 // check if any kernel mode APC's can be delivered. 00087 // 00088 00089 Thread->ApcState.KernelApcPending = FALSE; 00090 while (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]) == FALSE) { 00091 NextEntry = Thread->ApcState.ApcListHead[KernelMode].Flink; 00092 Apc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry); 00093 KernelRoutine = Apc->KernelRoutine; 00094 NormalRoutine = Apc->NormalRoutine; 00095 NormalContext = Apc->NormalContext; 00096 SystemArgument1 = Apc->SystemArgument1; 00097 SystemArgument2 = Apc->SystemArgument2; 00098 if (NormalRoutine == (PKNORMAL_ROUTINE)NULL) { 00099 00100 // 00101 // First entry in the kernel APC queue is a special kernel APC. 00102 // Remove the entry from the APC queue, set its inserted state 00103 // to FALSE, release dispatcher database lock, and call the kernel 00104 // routine. On return raise IRQL to dispatcher level and lock 00105 // dispatcher database lock. 00106 // 00107 00108 RemoveEntryList(NextEntry); 00109 Apc->Inserted = FALSE; 00110 KiUnlockApcQueue(Thread, OldIrql); 00111 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext, 00112 &SystemArgument1, &SystemArgument2); 00113 00114 #if DBG 00115 00116 if (KeGetCurrentIrql() != OldIrql) { 00117 KeBugCheckEx(IRQL_UNEXPECTED_VALUE, 00118 KeGetCurrentIrql() << 16 | OldIrql << 8, 00119 (ULONG_PTR)KernelRoutine, 00120 (ULONG_PTR)Apc, 00121 (ULONG_PTR)NormalRoutine); 00122 } 00123 00124 #endif 00125 00126 KiLockApcQueue(Thread, &OldIrql); 00127 00128 } else { 00129 00130 // 00131 // First entry in the kernel APC queue is a normal kernel APC. 00132 // If there is not a normal kernel APC in progress and kernel 00133 // APC's are not disabled, then remove the entry from the APC 00134 // queue, set its inserted state to FALSE, release the APC queue 00135 // lock, call the specified kernel routine, set kernel APC in 00136 // progress, lower the IRQL to zero, and call the normal kernel 00137 // APC routine. On return raise IRQL to dispatcher level, lock 00138 // the APC queue, and clear kernel APC in progress. 00139 // 00140 00141 if ((Thread->ApcState.KernelApcInProgress == FALSE) && 00142 (Thread->KernelApcDisable == 0)) { 00143 RemoveEntryList(NextEntry); 00144 Apc->Inserted = FALSE; 00145 KiUnlockApcQueue(Thread, OldIrql); 00146 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext, 00147 &SystemArgument1, &SystemArgument2); 00148 00149 #if DBG 00150 00151 if (KeGetCurrentIrql() != OldIrql) { 00152 KeBugCheckEx(IRQL_UNEXPECTED_VALUE, 00153 KeGetCurrentIrql() << 16 | OldIrql << 8 | 1, 00154 (ULONG_PTR)KernelRoutine, 00155 (ULONG_PTR)Apc, 00156 (ULONG_PTR)NormalRoutine); 00157 } 00158 00159 #endif 00160 00161 if (NormalRoutine != (PKNORMAL_ROUTINE)NULL) { 00162 Thread->ApcState.KernelApcInProgress = TRUE; 00163 KeLowerIrql(0); 00164 (NormalRoutine)(NormalContext, SystemArgument1, 00165 SystemArgument2); 00166 KeRaiseIrql(APC_LEVEL, &OldIrql); 00167 } 00168 00169 KiLockApcQueue(Thread, &OldIrql); 00170 Thread->ApcState.KernelApcInProgress = FALSE; 00171 00172 } else { 00173 KiUnlockApcQueue(Thread, OldIrql); 00174 return; 00175 } 00176 } 00177 } 00178 00179 // 00180 // Kernel APC queue is empty. If the previous mode is user, user APC 00181 // pending is set, and the user APC queue is not empty, then remove 00182 // the first entry from the user APC queue, set its inserted state to 00183 // FALSE, clear user APC pending, release the dispatcher database lock, 00184 // and call the specified kernel routine. If the normal routine address 00185 // is not NULL on return from the kernel routine, then initialize the 00186 // user mode APC context and return. Otherwise, check to determine if 00187 // another user mode APC can be processed. 00188 // 00189 00190 if ((IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]) == FALSE) && 00191 (PreviousMode == UserMode) && (Thread->ApcState.UserApcPending == TRUE)) { 00192 Thread->ApcState.UserApcPending = FALSE; 00193 NextEntry = Thread->ApcState.ApcListHead[UserMode].Flink; 00194 Apc = CONTAINING_RECORD(NextEntry, KAPC, ApcListEntry); 00195 KernelRoutine = Apc->KernelRoutine; 00196 NormalRoutine = Apc->NormalRoutine; 00197 NormalContext = Apc->NormalContext; 00198 SystemArgument1 = Apc->SystemArgument1; 00199 SystemArgument2 = Apc->SystemArgument2; 00200 RemoveEntryList(NextEntry); 00201 Apc->Inserted = FALSE; 00202 KiUnlockApcQueue(Thread, OldIrql); 00203 (KernelRoutine)(Apc, &NormalRoutine, &NormalContext, 00204 &SystemArgument1, &SystemArgument2); 00205 00206 if (NormalRoutine == (PKNORMAL_ROUTINE)NULL) { 00207 KeTestAlertThread(UserMode); 00208 00209 } else { 00210 KiInitializeUserApc(ExceptionFrame, TrapFrame, NormalRoutine, 00211 NormalContext, SystemArgument1, SystemArgument2); 00212 } 00213 00214 } else { 00215 KiUnlockApcQueue(Thread, OldIrql); 00216 } 00217 00218 return; 00219 }

BOOLEAN KiDisableInterrupts VOID   ) 
 

Referenced by KdPollBreakIn(), KeBugCheckEx(), KeEnterKernelDebugger(), KeFreezeExecution(), KiCalibrateTimeAdjustment(), KiCheckForSoftwareInterrupt(), KiFreezeTargetExecution(), KiI386PentiumLockErrataFixup(), KiLoadMTRR(), and KiLoadPAT().

VOID KiDispatchException IN PEXCEPTION_RECORD  ExceptionRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  FirstChance
 

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

References CONTEXT_FULL, DATA_BUS_ERROR, DbgkForwardException(), DbgPrint, DIVIDE_BREAKPOINT, FALSE, KDDEBUG_BREAKPOINT, KdIsThisAKdTrap(), KeBugCheckEx(), KeContextFromKframes(), KeContextToKframes(), KeGetCurrentPrcb, KeGetCurrentThread, KERNEL_BREAKPOINT_INSTRUCTION, KernelMode, KeUserExceptionDispatcher, KiCopyInformation(), KiDebugRoutine, KiEmulateByteWord(), KiEmulateDcbz(), KiEmulateReference(), KiEnableAlignmentFaultExceptions, KiFloatingException(), KiMachineCheck(), KMODE_EXCEPTION_NOT_HANDLED, NULL, ProbeForWrite(), PsGetCurrentProcess, RtlDispatchException(), TRUE, UDIVIDE_BREAKPOINT, and UserMode.

Referenced by Ki386CheckDelayedNpxTrap(), KiInitializeUserApc(), and KiRaiseException().

00422 : 00423 00424 This function is called to dispatch an exception to the proper mode and 00425 to cause the exception dispatcher to be called. 00426 00427 If the exception is a data misalignment, the previous mode is user, this 00428 is the first chance for handling the exception, and the current thread 00429 has enabled automatic alignment fixup, then an attempt is made to emulate 00430 the unaligned reference. Data misalignment exceptions are never emulated 00431 for kernel mode. 00432 00433 If the exception is a floating not implemented exception, then an attempt 00434 is made to emulate the floating operation. If the exception is an 00435 arithmetic exception, then an attempt is made to convert the imprecise 00436 exception into a precise exception, and then emulate the floating 00437 operation in order to obtain the proper IEEE results and exceptions. 00438 Floating exceptions are never emulated for kernel mode. 00439 00440 If the exception is neither a data misalignment nor a floating point 00441 exception and the previous mode is kernel, then the exception 00442 dispatcher is called directly to process the exception. Otherwise the 00443 exception record, exception frame, and trap frame contents are copied 00444 to the user mode stack. The contents of the exception frame and trap 00445 are then modified such that when control is returned, execution will 00446 commence in user mode in a routine which will call the exception 00447 dispatcher. 00448 00449 Arguments: 00450 00451 ExceptionRecord - Supplies a pointer to an exception record. 00452 00453 ExceptionFrame - Supplies a pointer to an exception frame. 00454 00455 TrapFrame - Supplies a pointer to a trap frame. 00456 00457 PreviousMode - Supplies the previous processor mode. 00458 00459 FirstChance - Supplies a boolean variable that specifies whether this 00460 is the first (TRUE) or second (FALSE) time that this exception has 00461 been processed. 00462 00463 Return Value: 00464 00465 None. 00466 00467 --*/ 00468 00469 { 00470 00471 CONTEXT ContextFrame; 00472 EXCEPTION_RECORD ExceptionRecord1; 00473 PEXC_SUM ExceptionSummary; 00474 LONG Length; 00475 ULONG SoftFpcr; 00476 ULONGLONG UserStack1; 00477 ULONGLONG UserStack2; 00478 00479 // 00480 // If the exception is an illegal instruction exception, then check for 00481 // a byte/word instruction that should be emulated. 00482 // 00483 // N.B. The exception code STATUS_ILLEGAL_INSTRUCTION may be converted 00484 // into STATUS_DATATYPE_MISALIGNMENT in the case of unaligned word 00485 // access. 00486 // 00487 00488 if (ExceptionRecord->ExceptionCode == STATUS_ILLEGAL_INSTRUCTION) { 00489 if (KiEmulateByteWord(ExceptionRecord, 00490 ExceptionFrame, 00491 TrapFrame) != FALSE) { 00492 KeGetCurrentPrcb()->KeByteWordEmulationCount += 1; 00493 goto Handled2; 00494 } 00495 } 00496 00497 #if DBG 00498 if (KiBreakOnAlignmentFault != FALSE) { 00499 00500 if (ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) { 00501 00502 DbgPrint("KI: Alignment fault exr = %p Pc = %p Address = %p\n", 00503 ExceptionRecord, 00504 ExceptionRecord->ExceptionAddress, 00505 ExceptionRecord->ExceptionInformation[2]); 00506 00507 DbgBreakPoint(); 00508 } 00509 } 00510 #endif 00511 00512 // 00513 // If the exception is a data misalignment, the previous mode was user, 00514 // this is the first chance for handling the exception, and the current 00515 // thread has enabled automatic alignment fixup, then attempt to emulate 00516 // the unaligned reference. 00517 // 00518 00519 if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) && 00520 (FirstChance != FALSE)) { 00521 00522 #if DBG 00523 00524 // 00525 // Count alignment faults by mode and display them at intervals. 00526 // 00527 00528 if (PreviousMode == KernelMode) { 00529 KiKernelFixupCount += 1; 00530 if ((KiKernelFixupCount & KiKernelFixupMask) == 0) { 00531 DbgPrint("KI: Kernel Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n", 00532 PsGetCurrentProcess()->UniqueProcessId, 00533 ExceptionRecord->ExceptionAddress, 00534 ExceptionRecord->ExceptionInformation[2], 00535 KiKernelFixupCount); 00536 } 00537 00538 } else { 00539 KiUserFixupCount += 1; 00540 if ((KiUserFixupCount & KiUserFixupMask) == 0) { 00541 DbgPrint("KI: User Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n", 00542 PsGetCurrentProcess()->UniqueProcessId, 00543 ExceptionRecord->ExceptionAddress, 00544 ExceptionRecord->ExceptionInformation[2], 00545 KiUserFixupCount); 00546 } 00547 } 00548 00549 #endif 00550 00551 // 00552 // If alignment fault exceptions are not enabled, then no exception 00553 // should be raised and the data reference should be emulated. 00554 // 00555 // We will emulate the reference if 00556 // KiEnableAlignmentFaultExceptions == 0 (always fix up all faults, the default) 00557 // OR The thread has explicitly enabled alignment fixups 00558 // OR KiEnableAlignmentFaultExceptions == 2 and the process is not being debugged 00559 // 00560 00561 if ( (KiEnableAlignmentFaultExceptions == 0) || 00562 00563 ((KeGetCurrentThread()->AutoAlignment != FALSE) || 00564 (KeGetCurrentThread()->ApcState.Process->AutoAlignment != FALSE)) || 00565 00566 (((PsGetCurrentProcess()->DebugPort == NULL) || (PreviousMode == KernelMode)) && 00567 (KiEnableAlignmentFaultExceptions == 2)) ) { 00568 00569 if (KiEmulateReference(ExceptionRecord, 00570 ExceptionFrame, 00571 TrapFrame, 00572 FALSE) != FALSE) { 00573 KeGetCurrentPrcb()->KeAlignmentFixupCount += 1; 00574 goto Handled2; 00575 } 00576 } 00577 } 00578 00579 // 00580 // If the exception is a data bus error then a machine check has 00581 // been trapped by the PALcode. The error will be forwarded to the 00582 // HAL eventually for logging or handling. If the handler returns 00583 // it is assumed that the HAL successfully handled the error and 00584 // execution may resume. 00585 // 00586 // N.B. A special exception code is used to signal a data bus error. 00587 // This code is equivalent to the bug check code merged with a 00588 // reserved facility code and the reserved bit set. 00589 // 00590 00591 if (ExceptionRecord->ExceptionCode == (DATA_BUS_ERROR | 0xdfff0000)) { 00592 KiMachineCheck(ExceptionRecord, ExceptionFrame, TrapFrame); 00593 goto Handled2; 00594 } 00595 00596 // 00597 // Initialize the copy of the software FPCR. The proper value is set 00598 // if a floating emulation operation is performed. Case on arithmetic 00599 // exception codes that require special handling by the kernel. 00600 // 00601 00602 SoftFpcr = 0; 00603 switch (ExceptionRecord->ExceptionCode) { 00604 00605 // 00606 // If the exception is a gentrap, then attempt to translate the 00607 // Alpha specific gentrap value to a status code value. This 00608 // exception is a precise trap. 00609 // 00610 // N.B. STATUS_ALPHA_GENTRAP is a pseudo status code generated by 00611 // PALcode when a callpal gentrap is executed. The status is 00612 // visible in user mode only when the gentrap code value is 00613 // unrecognized. 00614 // 00615 00616 case STATUS_ALPHA_GENTRAP : 00617 switch (ExceptionRecord->ExceptionInformation[0]) { 00618 case GENTRAP_INTEGER_OVERFLOW : 00619 ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW; 00620 break; 00621 00622 case GENTRAP_INTEGER_DIVIDE_BY_ZERO : 00623 ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO; 00624 break; 00625 00626 case GENTRAP_FLOATING_OVERFLOW : 00627 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW; 00628 break; 00629 00630 case GENTRAP_FLOATING_DIVIDE_BY_ZERO : 00631 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO; 00632 break; 00633 00634 case GENTRAP_FLOATING_UNDERFLOW : 00635 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW; 00636 break; 00637 00638 case GENTRAP_FLOATING_INVALID_OPERAND : 00639 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION; 00640 break; 00641 00642 case GENTRAP_FLOATING_INEXACT_RESULT : 00643 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT; 00644 break; 00645 } 00646 break; 00647 00648 // 00649 // If the exception is an unimplemented floating operation, then 00650 // PALcode has detected a subsetted floating point operation. These 00651 // include attempts to use round to plus or minus infinity rounding 00652 // modes on EV4. This exception is a fault. 00653 // 00654 // If the previous mode was user, an attempt is made to emulate the 00655 // operation. If the emulation is successful, the continuation 00656 // address is incremented to the next instruction. 00657 // 00658 // N.B. STATUS_ALPHA_FLOATING_NOT_IMPLEMENTED is a pseudo status code 00659 // generated by PALcode. The status is never visible outside of 00660 // this handler because the floating emulation routine converts 00661 // the status code to the proper floating status value. 00662 // 00663 00664 case STATUS_ALPHA_FLOATING_NOT_IMPLEMENTED : 00665 if (PreviousMode != KernelMode) { 00666 if (KiFloatingException(ExceptionRecord, 00667 ExceptionFrame, 00668 TrapFrame, 00669 FALSE, 00670 &SoftFpcr) != FALSE) { 00671 TrapFrame->Fir += 4; 00672 goto Handled2; 00673 } 00674 00675 } else { 00676 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION; 00677 } 00678 00679 break; 00680 00681 // 00682 // If the exception is an arithmetic exception, then one or more 00683 // integer overflow or floating point traps has occurred. This 00684 // exception is an imprecise (asynchronous) trap. Attempt to locate 00685 // the original trapping instruction and emulate the instruction. 00686 // 00687 // N.B. STATUS_ALPHA_ARITHMETIC_EXCEPTION is a pseudo status code 00688 // generated by PALcode. The status is never visible outside of 00689 // this handler because the floating emulation routine converts 00690 // the status code to the proper floating status value. 00691 // 00692 00693 case STATUS_ALPHA_ARITHMETIC_EXCEPTION : 00694 if (KiFloatingException(ExceptionRecord, 00695 ExceptionFrame, 00696 TrapFrame, 00697 TRUE, 00698 &SoftFpcr) != FALSE) { 00699 goto Handled2; 00700 } 00701 break; 00702 } 00703 00704 // 00705 // Move machine state from trap and exception frames to a context frame, 00706 // and increment the number of exceptions dispatched. 00707 // 00708 // Explicitly set the value of the software FPCR in the context frame 00709 // (because it is not a hardware register and thus not present in the 00710 // trap or exception frames). 00711 // 00712 00713 ContextFrame.ContextFlags = CONTEXT_FULL; 00714 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame); 00715 KeGetCurrentPrcb()->KeExceptionDispatchCount += 1; 00716 ContextFrame.SoftFpcr = (ULONGLONG)SoftFpcr; 00717 00718 // 00719 // Select the method of handling the exception based on the previous mode. 00720 // 00721 00722 if (PreviousMode == KernelMode) { 00723 00724 // 00725 // If the kernel debugger is active, the exception is a breakpoint, 00726 // the breakpoint is handled by the kernel debugger, and this is the 00727 // first chance, then give the kernel debugger a chance to handle 00728 // the exception. 00729 // 00730 00731 if ((FirstChance != FALSE) && (KiDebugRoutine != NULL) && 00732 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && 00733 (KdIsThisAKdTrap(ExceptionRecord, 00734 &ContextFrame, 00735 KernelMode) != FALSE) && 00736 00737 (((KiDebugRoutine) (TrapFrame, 00738 ExceptionFrame, 00739 ExceptionRecord, 00740 &ContextFrame, 00741 KernelMode, 00742 FALSE)) != FALSE)) { 00743 00744 goto Handled1; 00745 } 00746 00747 00748 // 00749 // Previous mode was kernel. 00750 // 00751 // If this is the first chance, then attempt to dispatch the exception 00752 // to a frame based handler. If the exception is handled, then continue 00753 // execution. 00754 // 00755 // If this is the second chance or the exception is not handled, 00756 // then if the kernel debugger is active, then give the kernel 00757 // debugger a second chance to handle the exception. If the kernel 00758 // debugger handles the exception, then continue execution. Otherwise 00759 // bug check. 00760 // 00761 00762 if (FirstChance != FALSE) { 00763 00764 // 00765 // This is the first chance to handle the exception. 00766 // 00767 00768 if (RtlDispatchException(ExceptionRecord, &ContextFrame) != FALSE) { 00769 goto Handled1; 00770 } 00771 } 00772 00773 // 00774 // This is the second chance to handle the exception. 00775 // 00776 00777 if ((KiDebugRoutine != NULL) && 00778 (((KiDebugRoutine) (TrapFrame, 00779 ExceptionFrame, 00780 ExceptionRecord, 00781 &ContextFrame, 00782 PreviousMode, 00783 TRUE)) != FALSE)) { 00784 00785 goto Handled1; 00786 } 00787 00788 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, 00789 ExceptionRecord->ExceptionCode, 00790 (ULONG_PTR)ExceptionRecord->ExceptionAddress, 00791 ExceptionRecord->ExceptionInformation[0], 00792 ExceptionRecord->ExceptionInformation[1]); 00793 00794 } else { 00795 00796 // 00797 // If the kernel debugger is active, the exception is a breakpoint, 00798 // the breakpoint is handled by the kernel debugger, and this is the 00799 // first chance, then give the kernel debugger a chance to handle 00800 // the exception. 00801 // 00802 00803 if ((FirstChance != FALSE) && 00804 (KiDebugRoutine != NULL) && 00805 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && 00806 (KdIsThisAKdTrap(ExceptionRecord, 00807 &ContextFrame, 00808 UserMode) != FALSE) && 00809 00810 ((PsGetCurrentProcess()->DebugPort == NULL) || 00811 ((PsGetCurrentProcess()->DebugPort != NULL) && 00812 (ExceptionRecord->ExceptionInformation[0] != 00813 DEBUG_STOP_BREAKPOINT)))) { 00814 00815 if (((KiDebugRoutine) (TrapFrame, 00816 ExceptionFrame, 00817 ExceptionRecord, 00818 &ContextFrame, 00819 UserMode, 00820 FALSE)) != FALSE) { 00821 00822 goto Handled1; 00823 } 00824 } 00825 00826 // 00827 // Previous mode was user. 00828 // 00829 // If this is the first chance and the current process has a debugger 00830 // port, then send a message to the debugger port and wait for a reply. 00831 // If the debugger handles the exception, then continue execution. Otherwise 00832 // transfer the exception information to the user stack, transition to 00833 // user mode, and attempt to dispatch the exception to a frame based 00834 // handler. If a frame based handler handles the exception, then continue 00835 // execution. Otherwise, execute the raise exception system service 00836 // which will call this routine a second time to process the exception. 00837 // 00838 // If this is the second chance and the current process has a debugger 00839 // port, then send a message to the debugger port and wait for a reply. 00840 // If the debugger handles the exception, then continue execution. Otherwise 00841 // if the current process has a subsystem port, then send a message to 00842 // the subsystem port and wait for a reply. If the subsystem handles the 00843 // exception, then continue execution. Otherwise terminate the thread. 00844 // 00845 00846 if (FirstChance != FALSE) { 00847 00848 // 00849 // This is the first chance to handle the exception. 00850 // 00851 00852 if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) { 00853 goto Handled2; 00854 } 00855 00856 // 00857 // Transfer exception information to the user stack, transition 00858 // to user mode, and attempt to dispatch the exception to a frame 00859 // based handler. 00860 // 00861 00862 repeat: 00863 try { 00864 00865 // 00866 // Compute length of exception record and new aligned stack 00867 // address. 00868 // 00869 00870 Length = (sizeof(EXCEPTION_RECORD) + 15) & (~15); 00871 UserStack1 = (ContextFrame.IntSp & ~((ULONG_PTR)15)) - Length; 00872 00873 // 00874 // Probe user stack area for writability and then transfer the 00875 // exception record to the user stack area. 00876 // 00877 00878 ProbeForWrite((PCHAR)UserStack1, Length, sizeof(QUAD)); 00879 RtlMoveMemory((PVOID)UserStack1, ExceptionRecord, Length); 00880 00881 // 00882 // Compute length of context record and new aligned user stack 00883 // pointer. 00884 // 00885 00886 Length = (sizeof(CONTEXT) + 15) & (~15); 00887 UserStack2 = UserStack1 - Length; 00888 00889 // 00890 // Probe user stack area for writability and then transfer the 00891 // context record to the user stack. 00892 // 00893 00894 ProbeForWrite((PCHAR)UserStack2, Length, sizeof(QUAD)); 00895 RtlMoveMemory((PVOID)UserStack2, &ContextFrame, sizeof(CONTEXT)); 00896 00897 // 00898 // Set address of exception record, context record, and the 00899 // and the new stack pointer in the current trap frame. 00900 // 00901 00902 TrapFrame->IntSp = UserStack2; 00903 TrapFrame->IntFp = UserStack2; 00904 ExceptionFrame->IntS0 = UserStack1; 00905 ExceptionFrame->IntS1 = UserStack2; 00906 00907 // 00908 // Set the address of the exception routine that will call the 00909 // exception dispatcher and then return to the trap handler. 00910 // The trap handler will restore the exception and trap frame 00911 // context and continue execution in the routine that will 00912 // call the exception dispatcher. 00913 // 00914 00915 TrapFrame->Fir = (ULONGLONG)(LONG_PTR)KeUserExceptionDispatcher; 00916 return; 00917 00918 // 00919 // If an exception occurs, then copy the new exception information 00920 // to an exception record and handle the exception. 00921 // 00922 00923 } except (KiCopyInformation(&ExceptionRecord1, 00924 (GetExceptionInformation())->ExceptionRecord)) { 00925 00926 // 00927 // If the exception is a stack overflow, then attempt 00928 // to raise the stack overflow exception. Otherwise, 00929 // the user's stack is not accessible, or is misaligned, 00930 // and second chance processing is performed. 00931 // 00932 00933 if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) { 00934 ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress; 00935 RtlMoveMemory((PVOID)ExceptionRecord, 00936 &ExceptionRecord1, sizeof(EXCEPTION_RECORD)); 00937 goto repeat; 00938 } 00939 } 00940 } 00941 00942 // 00943 // This is the second chance to handle the exception. 00944 // 00945 00946 if (DbgkForwardException(ExceptionRecord, TRUE, TRUE)) { 00947 goto Handled2; 00948 00949 } else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE)) { 00950 goto Handled2; 00951 00952 } else { 00953 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); 00954 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, 00955 ExceptionRecord->ExceptionCode, 00956 (ULONG_PTR)ExceptionRecord->ExceptionAddress, 00957 ExceptionRecord->ExceptionInformation[0], 00958 ExceptionRecord->ExceptionInformation[1]); 00959 00960 } 00961 } 00962 00963 // 00964 // Move machine state from context frame to trap and exception frames and 00965 // then return to continue execution with the restored state. 00966 // 00967 00968 Handled1: 00969 KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame, 00970 ContextFrame.ContextFlags, PreviousMode); 00971 00972 // 00973 // Exception was handled by the debugger or the associated subsystem 00974 // and state was modified, if necessary, using the get state and set 00975 // state capabilities. Therefore the context frame does not need to 00976 // be transferred to the trap and exception frames. 00977 // 00978 00979 Handled2: 00980 return; 00981 }

VOID KiDispatchInterrupt VOID   ) 
 

Referenced by KiDispatchSoftwareInterrupt(), and KiInitializeKernel().

PKTHREAD FASTCALL KiFindReadyThread IN ULONG  Processor,
KPRIORITY  LowPriority
 

VOID KiFloatingDispatch VOID   ) 
 

Referenced by KeConnectInterrupt(), KeDisconnectInterrupt(), and KiGetVectorInfo().

VOID KiFlushMultipleTb IN BOOLEAN  Invalid,
IN PVOID *  Virtual,
IN ULONG  Count
 

Referenced by KeFlushMultipleTb(), and KiFlushMultipleTbTarget().

VOID FASTCALL KiFlushSingleTb IN BOOLEAN  Invalid,
IN PVOID  Virtual
 

Referenced by ExFreePool(), KeFlushMultipleTb(), KeFlushSingleTb(), KiFlushSingleTbSynchronous(), KiFlushSingleTbTarget(), KiFlushTargetMultipleTb(), KiFlushTargetSingleTb(), KiFlushTargetSingleTbSynchronous(), MmDbgReleaseAddress(), MmDbgTranslatePhysicalAddress(), MmDbgTranslatePhysicalAddress64(), MmDbgWriteCheck(), MmMapMemoryDumpMdl(), and MmReleaseDumpAddresses().

VOID KiFreezeTargetExecution IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

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

References ContinueError, ContinueNextProcessor, FALSE, FREEZE_ACTIVE, FrozenState, HIGH_LEVEL, KCONTINUE_STATUS, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiDebugSwitchRoutine, KiDisableInterrupts(), KiFreezeOwner, KiRestoreInterrupts(), KiRestoreProcessorState(), KiSaveProcessorState(), NULL, RUNNING, Status, TARGET_FROZEN, and TRUE.

Referenced by KiIpiServiceRoutine(), and KiPollFreezeExecution().

00227 : 00228 00229 This function freezes the execution of the current running processor. 00230 If a trapframe is supplied to current state is saved into the prcb 00231 for the debugger. 00232 00233 Arguments: 00234 00235 TrapFrame - Supplies a pointer to the trap frame that describes the 00236 trap. 00237 00238 ExceptionFrame - Supplies a pointer to the exception frame that 00239 describes the trap. 00240 00241 Return Value: 00242 00243 None. 00244 00245 --*/ 00246 00247 { 00248 00249 #if !defined(NT_UP) 00250 00251 KIRQL OldIrql; 00252 PKPRCB Prcb; 00253 BOOLEAN Enable; 00254 KCONTINUE_STATUS Status; 00255 EXCEPTION_RECORD ExceptionRecord; 00256 00257 Enable = KiDisableInterrupts(); 00258 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00259 00260 Prcb = KeGetCurrentPrcb(); 00261 Prcb->IpiFrozen = TARGET_FROZEN; 00262 Prcb->SkipTick = TRUE; 00263 00264 if (TrapFrame != NULL) { 00265 KiSaveProcessorState(TrapFrame, ExceptionFrame); 00266 } 00267 00268 // 00269 // Sweep the data cache in case this is a system crash and the bug 00270 // check code is attempting to write a crash dump file. 00271 // 00272 00273 KeSweepCurrentDcache(); 00274 00275 // 00276 // Wait for person requesting us to freeze to 00277 // clear our frozen flag 00278 // 00279 00280 while (FrozenState(Prcb->IpiFrozen) == TARGET_FROZEN) { 00281 if (Prcb->IpiFrozen & FREEZE_ACTIVE) { 00282 00283 // 00284 // This processor has been made the active processor 00285 // 00286 if (TrapFrame) { 00287 RtlZeroMemory (&ExceptionRecord, sizeof ExceptionRecord); 00288 ExceptionRecord.ExceptionCode = STATUS_WAKE_SYSTEM_DEBUGGER; 00289 ExceptionRecord.ExceptionRecord = &ExceptionRecord; 00290 ExceptionRecord.ExceptionAddress = 00291 (PVOID)CONTEXT_TO_PROGRAM_COUNTER (&Prcb->ProcessorState.ContextFrame); 00292 00293 Status = (KiDebugSwitchRoutine) ( 00294 &ExceptionRecord, 00295 &Prcb->ProcessorState.ContextFrame, 00296 FALSE 00297 ); 00298 00299 } else { 00300 Status = ContinueError; 00301 } 00302 00303 // 00304 // If status is anything other then, continue with next 00305 // processor then reselect master 00306 // 00307 00308 if (Status != ContinueNextProcessor) { 00309 Prcb->IpiFrozen &= ~FREEZE_ACTIVE; 00310 KiFreezeOwner->IpiFrozen |= FREEZE_ACTIVE; 00311 } 00312 } 00313 KeYieldProcessor(); 00314 } 00315 00316 if (TrapFrame != NULL) { 00317 KiRestoreProcessorState(TrapFrame, ExceptionFrame); 00318 } 00319 00320 Prcb->IpiFrozen = RUNNING; 00321 00322 KeFlushCurrentTb(); 00323 KeSweepCurrentIcache(); 00324 00325 KeLowerIrql(OldIrql); 00326 KiRestoreInterrupts(Enable); 00327 #endif // !define(NT_UP) 00328 00329 return; 00330 }

PULONG KiGetUserModeStackAddress VOID   ) 
 

Referenced by KeUserModeCallback().

VOID KiInitializeContextThread IN PKTHREAD  Thread,
IN PKSYSTEM_ROUTINE  SystemRoutine,
IN PKSTART_ROUTINE StartRoutine  OPTIONAL,
IN PVOID StartContext  OPTIONAL,
IN PCONTEXT ContextFrame  OPTIONAL
 

Definition at line 71 of file i386/thredini.c.

References Context2, CONTEXT_CONTROL, CONTEXT_FLOATING_POINT, FALSE, KeContextToKframes(), KeI386FxsrPresent, KeI386NpxPresent, KeI386XMMIPresent, KernelMode, KiThreadStartup(), NULL, PASSIVE_LEVEL, TRUE, and UserMode.

00081 : 00082 00083 This function initializes the machine dependent context of a thread object. 00084 00085 N.B. This function does not check the accessibility of the context record. 00086 It is assumed the the caller of this routine is either prepared to 00087 handle access violations or has probed and copied the context record 00088 as appropriate. 00089 00090 Arguments: 00091 00092 Thread - Supplies a pointer to a dispatcher object of type thread. 00093 00094 SystemRoutine - Supplies a pointer to the system function that is to be 00095 called when the thread is first scheduled for execution. 00096 00097 StartRoutine - Supplies an optional pointer to a function that is to be 00098 called after the system has finished initializing the thread. This 00099 parameter is specified if the thread is a system thread and will 00100 execute totally in kernel mode. 00101 00102 StartContext - Supplies an optional pointer to an arbitrary data structure 00103 which will be passed to the StartRoutine as a parameter. This 00104 parameter is specified if the thread is a system thread and will 00105 execute totally in kernel mode. 00106 00107 ContextFrame - Supplies an optional pointer a context frame which contains 00108 the initial user mode state of the thread. This parameter is specified 00109 if the thread is a user thread and will execute in user mode. If this 00110 parameter is not specified, then the Teb parameter is ignored. 00111 00112 Return Value: 00113 00114 None. 00115 00116 --*/ 00117 00118 { 00119 PFX_SAVE_AREA NpxFrame; 00120 PKSWITCHFRAME SwitchFrame; 00121 PKTRAP_FRAME TrFrame; 00122 PULONG PSystemRoutine; 00123 PULONG PStartRoutine; 00124 PULONG PStartContext; 00125 PULONG PUserContextFlag; 00126 ULONG ContextFlags; 00127 CONTEXT Context2; 00128 PCONTEXT ContextFrame2 = NULL; 00129 PFXSAVE_FORMAT PFxSaveArea; 00130 00131 // 00132 // If a context frame is specified, then initialize a trap frame and 00133 // and an exception frame with the specified user mode context. 00134 // 00135 00136 if (ARGUMENT_PRESENT(ContextFrame)) { 00137 00138 RtlMoveMemory(&Context2, ContextFrame, sizeof(CONTEXT)); 00139 ContextFrame2 = &Context2; 00140 ContextFlags = CONTEXT_CONTROL; 00141 00142 // 00143 // The 80387 save area is at the very base of the kernel stack. 00144 // 00145 00146 NpxFrame = (PFX_SAVE_AREA)(((ULONG)(Thread->InitialStack) - 00147 sizeof(FX_SAVE_AREA))); 00148 00149 // 00150 // Load up an initial NPX state. 00151 // 00152 00153 if (KeI386XMMIPresent == TRUE) { 00154 PFxSaveArea = (PFXSAVE_FORMAT)ContextFrame2->ExtendedRegisters; 00155 00156 PFxSaveArea->ControlWord = 0x27f; // like fpinit but 64bit mode 00157 PFxSaveArea->StatusWord = 0; 00158 PFxSaveArea->TagWord = 0; 00159 PFxSaveArea->ErrorOffset = 0; 00160 PFxSaveArea->ErrorSelector = 0; 00161 PFxSaveArea->DataOffset = 0; 00162 PFxSaveArea->DataSelector = 0; 00163 PFxSaveArea->MXCsr = 0x1f80; // mask all the exceptions 00164 } else { 00165 ContextFrame2->FloatSave.ControlWord = 0x27f; // like fpinit but 64bit mode 00166 ContextFrame2->FloatSave.StatusWord = 0; 00167 ContextFrame2->FloatSave.TagWord = 0xffff; 00168 ContextFrame2->FloatSave.ErrorOffset = 0; 00169 ContextFrame2->FloatSave.ErrorSelector = 0; 00170 ContextFrame2->FloatSave.DataOffset = 0; 00171 ContextFrame2->FloatSave.DataSelector = 0; 00172 } 00173 00174 00175 if (KeI386NpxPresent) { 00176 ContextFrame2->FloatSave.Cr0NpxState = 0; 00177 NpxFrame->Cr0NpxState = 0; 00178 NpxFrame->NpxSavedCpu = 0; 00179 if (KeI386XMMIPresent == TRUE) { 00180 ContextFlags |= CONTEXT_EXTENDED_REGISTERS; 00181 } else { 00182 ContextFlags |= CONTEXT_FLOATING_POINT; 00183 } 00184 00185 // 00186 // Threads NPX state is not in the coprocessor. 00187 // 00188 00189 Thread->NpxState = NPX_STATE_NOT_LOADED; 00190 Thread->NpxIrql = PASSIVE_LEVEL; 00191 00192 } else { 00193 NpxFrame->Cr0NpxState = CR0_EM; 00194 00195 // 00196 // Threads NPX state is not in the coprocessor. 00197 // In the emulator case, do not set the CR0_EM bit as their 00198 // emulators may not want exceptions on FWAIT instructions. 00199 // 00200 00201 Thread->NpxState = NPX_STATE_NOT_LOADED & ~CR0_MP; 00202 } 00203 00204 // 00205 // Force debug registers off. They won't work anyway from an 00206 // initial frame, debuggers must set a hard breakpoint in the target 00207 // 00208 00209 ContextFrame2->Dr0 = 0; 00210 ContextFrame2->Dr1 = 0; 00211 ContextFrame2->Dr2 = 0; 00212 ContextFrame2->Dr3 = 0; 00213 ContextFrame2->Dr6 = 0; 00214 ContextFrame2->Dr7 = 0; 00215 ContextFrame2->ContextFlags &= ~(CONTEXT_DEBUG_REGISTERS); 00216 #if 0 00217 // 00218 // If AutoAlignment is FALSE, we want to set the Alignment Check bit 00219 // in Eflags, so we will get alignment faults. 00220 // 00221 00222 if (Thread->AutoAlignment == FALSE) { 00223 ContextFrame2->EFlags |= EFLAGS_ALIGN_CHECK; 00224 } 00225 #endif 00226 // 00227 // If the thread is set 00228 00229 TrFrame = (PKTRAP_FRAME)(((ULONG)NpxFrame - KTRAP_FRAME_LENGTH)); 00230 00231 // Space for arguments to KiThreadStartup. Order is important, 00232 // Since args are passed on stack through KiThreadStartup to 00233 // PStartRoutine with PStartContext as an argument. 00234 00235 PUserContextFlag = (PULONG)TrFrame - 1; 00236 PStartContext = PUserContextFlag - 1; 00237 PStartRoutine = PStartContext - 1; 00238 PSystemRoutine = PStartRoutine - 1; 00239 00240 SwitchFrame = (PKSWITCHFRAME)((PUCHAR)PSystemRoutine - 00241 sizeof(KSWITCHFRAME)); 00242 00243 // 00244 // Copy information from the specified context frame to the trap and 00245 // exception frames. 00246 // 00247 00248 KeContextToKframes(TrFrame, NULL, ContextFrame2, 00249 ContextFrame2->ContextFlags | ContextFlags, 00250 UserMode); 00251 00252 TrFrame->HardwareSegSs |= RPL_MASK; 00253 TrFrame->SegDs |= RPL_MASK; 00254 TrFrame->SegEs |= RPL_MASK; 00255 00256 #if DBG 00257 TrFrame->DbgArgMark = 0xBADB0D00; 00258 #endif 00259 00260 // 00261 // Tell KiThreadStartup that a user context is present. 00262 // 00263 00264 *PUserContextFlag = 1; 00265 00266 00267 // 00268 // Initialize the kernel mode ExceptionList pointer 00269 // 00270 00271 TrFrame->ExceptionList = EXCEPTION_CHAIN_END; 00272 00273 // 00274 // Initialize the saved previous processor mode. 00275 // 00276 00277 TrFrame->PreviousPreviousMode = UserMode; 00278 00279 // 00280 // Set the previous mode in thread object to user. 00281 // 00282 00283 Thread->PreviousMode = UserMode; 00284 00285 00286 } else { 00287 00288 // 00289 // Dummy floating save area. Kernel threads don't have or use 00290 // the floating point - the dummy save area is make the stacks 00291 // consistent. 00292 // 00293 00294 NpxFrame = (PFX_SAVE_AREA)(((ULONG)(Thread->InitialStack) - 00295 sizeof(FX_SAVE_AREA))); 00296 00297 // 00298 // Load up an initial NPX state. 00299 // 00300 RtlZeroMemory((PVOID)NpxFrame, sizeof(FX_SAVE_AREA)); 00301 00302 if (KeI386FxsrPresent == TRUE) { 00303 NpxFrame->U.FxArea.ControlWord = 0x27f;//like fpinit but 64bit mode 00304 NpxFrame->U.FxArea.MXCsr = 0x1f80;// mask all the exceptions 00305 } else { 00306 NpxFrame->U.FnArea.ControlWord = 0x27f;//like fpinit but 64bit mode 00307 NpxFrame->U.FnArea.TagWord = 0xffff; 00308 } 00309 00310 // 00311 // Threads NPX state is not in the coprocessor. 00312 // 00313 00314 Thread->NpxState = NPX_STATE_NOT_LOADED; 00315 00316 // 00317 // Space for arguments to KiThreadStartup. 00318 // Order of fields in the switchframe is important, 00319 // Since args are passed on stack through KiThreadStartup to 00320 // PStartRoutine with PStartContext as an argument. 00321 // 00322 00323 PUserContextFlag = (PULONG)((ULONG)NpxFrame) - 1; 00324 00325 PStartContext = PUserContextFlag - 1; 00326 PStartRoutine = PStartContext - 1; 00327 PSystemRoutine = PStartRoutine - 1; 00328 00329 SwitchFrame = (PKSWITCHFRAME)((PUCHAR)PSystemRoutine - 00330 sizeof(KSWITCHFRAME)); 00331 00332 00333 // 00334 // Tell KiThreadStartup that a user context is NOT present. 00335 // 00336 00337 *PUserContextFlag = 0; 00338 00339 00340 // 00341 // Set the previous mode in thread object to kernel. 00342 // 00343 00344 Thread->PreviousMode = KernelMode; 00345 } 00346 00347 // 00348 // Set up thread start parameters. 00349 // (UserContextFlag set above) 00350 // 00351 00352 *PStartContext = (ULONG)StartContext; 00353 *PStartRoutine = (ULONG)StartRoutine; 00354 *PSystemRoutine = (ULONG)SystemRoutine; 00355 00356 00357 // 00358 // Set up switch frame. Assume the thread doesn't use the 80387; 00359 // if it ever does (and there is one), these flags will get reset. 00360 // Each thread starts with these same flags set, regardless of 00361 // whether the hardware exists or not. 00362 // 00363 00364 SwitchFrame->RetAddr = (ULONG)KiThreadStartup; 00365 00366 SwitchFrame->Eflags = EFLAGS_INTERRUPT_MASK; 00367 00368 #if 0 00369 // 00370 // If AutoAlignment is FALSE, we want to set the Alignment Check bit 00371 // in Eflags, so we will get alignment faults. 00372 // 00373 00374 if (Thread->AutoAlignment == FALSE) { 00375 SwitchFrame->Eflags |= EFLAGS_ALIGN_CHECK; 00376 } 00377 #endif 00378 00379 SwitchFrame->ExceptionList = (ULONG)(EXCEPTION_CHAIN_END); 00380 00381 // 00382 // Set the initial kernel stack pointer. 00383 // 00384 00385 //DbgPrint("KiInitializeContextThread Thread %08x SwitchFrame %08x\n", Thread, SwitchFrame); 00386 //DbgPrint("PSystemRoutine %08x PStartRoutine %08x PStartContext %08x\n", *PSystemRoutine, *PStartRoutine, *PStartContext); 00387 00388 Thread->KernelStack = (PVOID)SwitchFrame; 00389 return; 00390 }

VOID KiInitializeKernel IN PKPROCESS  Process,
IN PKTHREAD  Thread,
IN PVOID  IdleStack,
IN PKPRCB  Prcb,
IN CCHAR  Number,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock
 

Definition at line 65 of file alpha/initkr.c.

References APC_LEVEL, _BOOT_STATUS::BootFinished, _RESTART_BLOCK::BootStatus, CcMasterSpinLock, CcVacbSpinLock, DBG_STATUS_CONTROL_C, DbgPrint, DISPATCH_LEVEL, DMA_READ_DCACHE_INVALIDATE, DMA_WRITE_DCACHE_SNOOP, EXCEPTION_EXECUTE_HANDLER, ExpInitializeExecutive(), FALSE, HalInitializeProcessor(), HIGH_LEVEL, Index, KdInitSystem(), KdPollBreakIn(), KeActiveProcessors, KeBugCheck(), KeBugCheckEx(), KeFeatureBits, KeFlushCurrentTb(), KeInitializeDpc(), KeInitializeProcess(), KeInitializeSpinLock(), KeInitializeThread(), KeLoaderBlock, KeMaximumIncrement, KeNumberProcessors, KeProcessorArchitecture, KeProcessorLevel, KeProcessorRevision, KeRaiseIrql(), KeSetPriorityThread(), KiAdjustDpcThreshold, KiApcInterrupt(), KiComputeReciprocal(), KiContextSwapLock, KiDisableAlignmentExceptions, KiDispatcherLock, KiDispatchInterrupt(), KiDmaIoCoherency, KiGetFeatureBits(), KiIdleSummary, KiInitExceptionFilter(), KiInitSystem(), KiMaximumDpcQueueDepth, KiMinimumDpcRate, KiPassiveRelease(), KiPhase0SyncIoMap(), KiProcessorBlock, KiQuantumEnd, KiTimeIncrementReciprocal, KiTimeIncrementShiftCount, KiUnexpectedInterrupt(), LockQueueContextSwapLock, LockQueueDispatcherLock, LockQueueMasterLock, LockQueuePfnLock, LockQueueSystemSpaceLock, LockQueueVacbLock, MAXIMUM_PROCESSORS, MmPfnLock, MmSystemSpaceLock, NIL, NULL, PAGE_SHIFT, PAGE_SIZE, PASSIVE_LEVEL, PDI_SHIFT, PKDEFERRED_ROUTINE, PKSTART_ROUTINE, PKSYSTEM_ROUTINE, PoInitializePrcb(), PRCB_MAJOR_VERSION, PRCB_MINOR_VERSION, Running, SetMember, TRUE, and USHORT.

00076 : 00077 00078 This function gains control after the system has been bootstrapped and 00079 before the system has been initialized. Its function is to initialize 00080 the kernel data structures, initialize the idle thread and process objects, 00081 initialize the processor control block, call the executive initialization 00082 routine, and then return to the system startup routine. This routine is 00083 also called to initialize the processor specific structures when a new 00084 processor is brought on line. 00085 00086 Arguments: 00087 00088 Process - Supplies a pointer to a control object of type process for 00089 the specified processor. 00090 00091 Thread - Supplies a pointer to a dispatcher object of type thread for 00092 the specified processor. 00093 00094 IdleStack - Supplies a pointer the base of the real kernel stack for 00095 idle thread on the specified processor. 00096 00097 Prcb - Supplies a pointer to a processor control block for the specified 00098 processor. 00099 00100 Number - Supplies the number of the processor that is being 00101 initialized. 00102 00103 LoaderBlock - Supplies a pointer to the loader parameter block. 00104 00105 Return Value: 00106 00107 None. 00108 00109 --*/ 00110 00111 { 00112 00113 UCHAR DataByte; 00114 ULONG DataLong; 00115 LONG Index; 00116 KIRQL OldIrql; 00117 PKPCR Pcr = PCR; 00118 struct _RESTART_BLOCK *RestartBlock; 00119 00120 // 00121 // Save the address of the loader parameter block. 00122 // 00123 00124 KeLoaderBlock = LoaderBlock; 00125 00126 // 00127 // Set the appropriate member in the active processors set. 00128 // 00129 00130 SetMember(Number, KeActiveProcessors); 00131 00132 // 00133 // Set the number of processors based on the maximum of the current 00134 // number of processors and the current processor number. 00135 // 00136 00137 if ((Number + 1) > KeNumberProcessors) { 00138 KeNumberProcessors = Number + 1; 00139 } 00140 00141 // 00142 // Set the maximum address space number to the minimum of all maximum 00143 // address space numbers passed via the loader block. 00144 // 00145 00146 if (Number == 0) { 00147 KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber; 00148 00149 } else if (KiMaximumAsn > LoaderBlock->u.Alpha.MaximumAddressSpaceNumber) { 00150 KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber; 00151 } 00152 00153 // 00154 // Initialize the passive release, APC, and DPC interrupt vectors. 00155 // 00156 00157 Pcr->InterruptRoutine[0] = KiPassiveRelease; 00158 Pcr->InterruptRoutine[APC_LEVEL] = KiApcInterrupt; 00159 Pcr->InterruptRoutine[DISPATCH_LEVEL] = KiDispatchInterrupt; 00160 Pcr->ReservedVectors = 00161 (1 << PASSIVE_LEVEL) | (1 << APC_LEVEL) | (1 << DISPATCH_LEVEL); 00162 00163 // 00164 // Initialize the processor id fields in the PCR. 00165 // 00166 00167 Pcr->Number = Number; 00168 Pcr->SetMember = 1 << Number; 00169 Pcr->NotMember = ~Pcr->SetMember; 00170 00171 // 00172 // Initialize the processor block. 00173 // 00174 00175 Prcb->MinorVersion = PRCB_MINOR_VERSION; 00176 Prcb->MajorVersion = PRCB_MAJOR_VERSION; 00177 Prcb->BuildType = 0; 00178 00179 #if DBG 00180 00181 Prcb->BuildType |= PRCB_BUILD_DEBUG; 00182 00183 #endif 00184 00185 #ifdef NT_UP 00186 00187 Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR; 00188 00189 #endif 00190 00191 Prcb->CurrentThread = Thread; 00192 Prcb->NextThread = (PKTHREAD)NULL; 00193 Prcb->IdleThread = Thread; 00194 Prcb->Number = Number; 00195 Prcb->SetMember = 1 << Number; 00196 00197 KeInitializeDpc(&Prcb->QuantumEndDpc, 00198 (PKDEFERRED_ROUTINE)KiQuantumEnd, 00199 NIL); 00200 00201 // 00202 // initialize the per processor lock queue entry for implemented locks. 00203 // 00204 00205 #if !defined(NT_UP) 00206 00207 Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL; 00208 Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock; 00209 Prcb->LockQueue[LockQueueContextSwapLock].Next = NULL; 00210 Prcb->LockQueue[LockQueueContextSwapLock].Lock = &KiContextSwapLock; 00211 Prcb->LockQueue[LockQueuePfnLock].Next = NULL; 00212 Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock; 00213 Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL; 00214 Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock; 00215 Prcb->LockQueue[LockQueueMasterLock].Next = NULL; 00216 Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock; 00217 Prcb->LockQueue[LockQueueVacbLock].Next = NULL; 00218 Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock; 00219 00220 #endif 00221 00222 // 00223 // Set address of PCR in PRCB. 00224 // 00225 00226 Prcb->Pcr = Pcr; 00227 00228 // 00229 // Initialize the interprocessor communication packet. 00230 // 00231 00232 #if !defined(NT_UP) 00233 00234 Prcb->TargetSet = 0; 00235 Prcb->WorkerRoutine = NULL; 00236 Prcb->RequestSummary = 0; 00237 Prcb->IpiFrozen = 0; 00238 00239 #if NT_INST 00240 00241 Prcb->IpiCounts = &KiIpiCounts[Number]; 00242 00243 #endif //NT_INST 00244 00245 #endif //NT_UP 00246 00247 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth; 00248 Prcb->MinimumDpcRate = KiMinimumDpcRate; 00249 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; 00250 00251 // 00252 // Initialize DPC listhead and lock. 00253 // 00254 00255 InitializeListHead(&Prcb->DpcListHead); 00256 KeInitializeSpinLock(&Prcb->DpcLock); 00257 00258 // 00259 // Set address of processor block. 00260 // 00261 00262 KiProcessorBlock[Number] = Prcb; 00263 00264 // 00265 // Set address of process object in thread object. 00266 // 00267 00268 Thread->ApcState.Process = Process; 00269 00270 // 00271 // Set the appropriate member in the active processors set. 00272 // 00273 00274 SetMember( Number, KeActiveProcessors ); 00275 00276 // 00277 // Set the number of processors based on the maximum of the current 00278 // number of processors and the current processor number. 00279 // 00280 00281 if( (Number+1) > KeNumberProcessors ){ 00282 KeNumberProcessors = Number + 1; 00283 } 00284 00285 // 00286 // Initialize processors PowerState 00287 // 00288 00289 PoInitializePrcb (Prcb); 00290 00291 // 00292 // Set global processor architecture, level and revision. The 00293 // latter two are the least common denominator on an MP system. 00294 // 00295 00296 #ifdef _AXP64_ 00297 KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA64; 00298 #else 00299 KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA; 00300 #endif 00301 00302 if ((KeProcessorLevel == 0) || 00303 (KeProcessorLevel > (USHORT)Pcr->ProcessorType)) { 00304 KeProcessorLevel = (USHORT)Pcr->ProcessorType; 00305 } 00306 00307 if ((KeProcessorRevision == 0) || 00308 (KeProcessorRevision > (USHORT)Pcr->ProcessorRevision)) { 00309 KeProcessorRevision = (USHORT)Pcr->ProcessorRevision; 00310 } 00311 00312 // 00313 // Initialize all interrupt vectors to transfer control to the unexpected 00314 // interrupt routine. 00315 // 00316 // N.B. This interrupt object is never actually "connected" to an interrupt 00317 // vector via KeConnectInterrupt. It is initialized and then connected 00318 // by simply storing the address of the dispatch code in the interrupt 00319 // vector. 00320 // 00321 00322 if (Number == 0) { 00323 00324 KeFeatureBits = KiGetFeatureBits(); 00325 00326 // 00327 // Initial the address of the interrupt dispatch routine. 00328 // 00329 00330 KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt; 00331 00332 // 00333 // Initialize the context swap spinlock. 00334 // 00335 00336 KeInitializeSpinLock(&KiContextSwapLock); 00337 00338 // 00339 // Copy the interrupt dispatch code template into the interrupt object 00340 // and flush the dcache on all processors that the current thread can 00341 // run on to ensure that the code is actually in memory. 00342 // 00343 00344 for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) { 00345 KxUnexpectedInterrupt.DispatchCode[Index] = KiInterruptTemplate[Index]; 00346 } 00347 00348 // 00349 // Sweep the instruction cache on the current processor. 00350 // 00351 00352 KiImb(); 00353 00354 } else { 00355 00356 // 00357 // Mask off feature bits that are not supported on all processors. 00358 // 00359 00360 KeFeatureBits &= KiGetFeatureBits(); 00361 } 00362 00363 // 00364 // Update processor features 00365 // 00366 00367 SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = 00368 (KeFeatureBits & KF_BYTE) ? TRUE : FALSE; 00369 00370 for (Index = DISPATCH_LEVEL+1; Index < MAXIMUM_VECTOR; Index += 1) { 00371 Pcr->InterruptRoutine[Index] = (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode); 00372 } 00373 00374 // 00375 // Raise IRQL to APC level. 00376 // 00377 00378 KeRaiseIrql(APC_LEVEL, &OldIrql); 00379 00380 // 00381 // If the initial processor is being initialized, then initialize the 00382 // per system data structures. 00383 // 00384 00385 if (Number == 0) { 00386 00387 // 00388 // Initialize the address of the restart block for the boot master. 00389 // 00390 00391 Prcb->RestartBlock = SYSTEM_BLOCK->RestartBlock; 00392 00393 // 00394 // Initialize the kernel debugger if enabled by the load options. 00395 // 00396 00397 if (KdInitSystem(LoaderBlock, FALSE) == FALSE) { 00398 KeBugCheck(PHASE0_INITIALIZATION_FAILED); 00399 } 00400 00401 #if DBG 00402 00403 // 00404 // Allow a breakin to the kernel debugger if one is pending. 00405 // 00406 00407 if (KdPollBreakIn() != FALSE){ 00408 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 00409 } 00410 00411 #endif //DBG 00412 00413 // 00414 // Initialize processor block array. 00415 // 00416 00417 for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) { 00418 KiProcessorBlock[Index] = (PKPRCB)NULL; 00419 } 00420 00421 // 00422 // Initialize default DMA coherency value for Alpha. 00423 // 00424 00425 KiDmaIoCoherency = DMA_READ_DCACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP; 00426 00427 // 00428 // Perform architecture independent initialization. 00429 // 00430 00431 KiInitSystem(); 00432 00433 // 00434 // Initialize idle thread process object and then set: 00435 // 00436 // 1. all the quantum values to the maximum possible. 00437 // 2. the process in the balance set. 00438 // 3. the active processor mask to the specified processor. 00439 // 00440 00441 KeInitializeProcess(Process, 00442 (KPRIORITY)0, 00443 (KAFFINITY)(0xffffffff), 00444 (PULONG_PTR)PDE_SELFMAP, 00445 FALSE); 00446 00447 Process->ThreadQuantum = MAXCHAR; 00448 } 00449 00450 // 00451 // Initialize idle thread object and then set: 00452 // 00453 // 1. the initial kernel stack to the specified idle stack. 00454 // 2. the next processor number to the specified processor. 00455 // 3. the thread priority to the highest possible value. 00456 // 4. the state of the thread to running. 00457 // 5. the thread affinity to the specified processor. 00458 // 6. the specified processor member in the process active processors 00459 // set. 00460 // 00461 00462 KeInitializeThread(Thread, 00463 (PVOID)((ULONG_PTR)IdleStack - PAGE_SIZE), 00464 (PKSYSTEM_ROUTINE)NULL, 00465 (PKSTART_ROUTINE)NULL, 00466 (PVOID)NULL, 00467 (PCONTEXT)NULL, 00468 (PVOID)NULL, 00469 Process); 00470 00471 Thread->InitialStack = IdleStack; 00472 Thread->StackBase = IdleStack; 00473 Thread->StackLimit = (PVOID)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE); 00474 Thread->NextProcessor = Number; 00475 Thread->Priority = HIGH_PRIORITY; 00476 Thread->State = Running; 00477 Thread->Affinity = (KAFFINITY)(1 << Number); 00478 Thread->WaitIrql = DISPATCH_LEVEL; 00479 00480 // 00481 // If the current processor is the boot master then set the appropriate 00482 // bit in the active summary of the idle process. 00483 // 00484 00485 if (Number == 0) { 00486 SetMember(Number, Process->ActiveProcessors); 00487 } 00488 00489 // 00490 // call the executive initialization routine. 00491 // 00492 00493 try { 00494 ExpInitializeExecutive(Number, LoaderBlock); 00495 00496 } except(KeBugCheckEx(PHASE0_EXCEPTION, 00497 (ULONG)GetExceptionCode(), 00498 (ULONG_PTR)GetExceptionInformation(), 00499 0,0), EXCEPTION_EXECUTE_HANDLER) { 00500 ; // should never get here 00501 } 00502 00503 // 00504 // If the initial processor is being initialized, then compute the 00505 // timer table reciprocal value and reset the PRCB values for 00506 // the controllable DPC behavior in order to reflect any registry 00507 // overrides. 00508 // 00509 00510 if (Number == 0) { 00511 KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement, 00512 &KiTimeIncrementShiftCount); 00513 00514 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth; 00515 Prcb->MinimumDpcRate = KiMinimumDpcRate; 00516 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; 00517 } 00518 00519 // 00520 // Try to enable automatic PAL code fixups on this processor. 00521 // This must be done after the configuration values are read 00522 // out of the registry in ExpInitializeExecutive. 00523 // 00524 00525 KiDisableAlignmentExceptions(); 00526 00527 // 00528 // 00529 // Raise IRQL to dispatch level and set the priority of the idle thread 00530 // to zero. This will have the effect of immediately causing the phase 00531 // one initialization thread to get scheduled for execution. The idle 00532 // thread priority is then set to the lowest realtime priority. 00533 // 00534 00535 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 00536 KeSetPriorityThread(Thread, (KPRIORITY)0); 00537 Thread->Priority = LOW_REALTIME_PRIORITY; 00538 00539 // 00540 // Raise IRQL to the highest level. 00541 // 00542 00543 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00544 00545 // 00546 // If a restart block exists for the current processor then set boot 00547 // completed. 00548 // 00549 00550 #if !defined(NT_UP) 00551 00552 RestartBlock = Prcb->RestartBlock; 00553 if (RestartBlock != NULL) { 00554 RestartBlock->BootStatus.BootFinished = 1; 00555 } 00556 00557 // 00558 // If the current processor is a secondary processor and a thread has 00559 // not been selected for execution, then set the appropriate bit in the 00560 // idle summary. 00561 // 00562 00563 if ((Number != 0) && (Prcb->NextThread == NULL)) { 00564 SetMember(Number, KiIdleSummary); 00565 } 00566 00567 #endif //NT_UP 00568 00569 return; 00570 }

VOID KiInitializeUserApc IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN PKNORMAL_ROUTINE  NormalRoutine,
IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 33 of file alpha/apcuser.c.

References CONTEXT_FULL, KeContextFromKframes(), KeUserApcDispatcher, KiCopyInformation(), KiDispatchException(), ProbeForWrite(), STK_MIN_FRAME, TRUE, and UserMode.

Referenced by KiDeliverApc().

00044 : 00045 00046 This function is called to initialize the context for a user mode APC. 00047 00048 Arguments: 00049 00050 ExceptionFrame - Supplies a pointer to an exception frame. 00051 00052 TrapFrame - Supplies a pointer to a trap frame. 00053 00054 NormalRoutine - Supplies a pointer to the user mode APC routine. 00055 00056 NormalContext - Supplies a pointer to the user context for the APC 00057 routine. 00058 00059 SystemArgument1 - Supplies the first system supplied value. 00060 00061 SystemArgument2 - Supplies the second system supplied value. 00062 00063 Return Value: 00064 00065 None. 00066 00067 --*/ 00068 00069 { 00070 00071 CONTEXT ContextRecord; 00072 EXCEPTION_RECORD ExceptionRecord; 00073 LONG_PTR Length; 00074 ULONG_PTR UserStack; 00075 00076 // 00077 // Move the user mode state from the trap and exception frames to the 00078 // context frame. 00079 // 00080 00081 ContextRecord.ContextFlags = CONTEXT_FULL; 00082 KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextRecord); 00083 00084 // 00085 // Transfer the context information to the user stack, initialize the 00086 // APC routine parameters, and modify the trap frame so execution will 00087 // continue in user mode at the user mode APC dispatch routine. 00088 // 00089 00090 try { 00091 00092 // 00093 // Compute length of context record and new aligned user stack pointer. 00094 // 00095 00096 Length = (sizeof(CONTEXT) + 15) & (~15); 00097 UserStack = ((ULONG_PTR)ContextRecord.IntSp & (~15)) - Length; 00098 00099 // 00100 // Probe user stack area for writeability and then transfer the 00101 // context record to the user stack. 00102 // 00103 00104 ProbeForWrite((PVOID)UserStack, (ULONG)Length, sizeof(QUAD)); 00105 RtlMoveMemory((PVOID)UserStack, &ContextRecord, sizeof(CONTEXT)); 00106 00107 // 00108 // Set the address of the user APC routine, the APC parameters, the 00109 // new frame pointer, and the new stack pointer in the current trap 00110 // frame. Set the continuation address so control will be transferred 00111 // to the user APC dispatcher. 00112 // 00113 // N.B. It is not possible to pass 64 bit arguments to the routine. 00114 // N.B. ULONG becomes canonical longword with (ULONGLONG)(LONG) cast. 00115 // 00116 // 00117 00118 TrapFrame->IntSp = (ULONGLONG)(LONG_PTR)UserStack; 00119 TrapFrame->IntFp = (ULONGLONG)(LONG_PTR)UserStack; 00120 TrapFrame->IntA0 = (ULONGLONG)(LONG_PTR)NormalContext; 00121 TrapFrame->IntA1 = (ULONGLONG)(LONG_PTR)SystemArgument1; 00122 TrapFrame->IntA2 = (ULONGLONG)(LONG_PTR)SystemArgument2; 00123 TrapFrame->IntA3 = (ULONGLONG)(LONG_PTR)NormalRoutine; 00124 TrapFrame->Fir = (ULONGLONG)(LONG_PTR)KeUserApcDispatcher; 00125 00126 // 00127 // If an exception occurs, then copy the exception information to an 00128 // exception record and handle the exception. 00129 // 00130 00131 } except (KiCopyInformation(&ExceptionRecord, 00132 (GetExceptionInformation())->ExceptionRecord)) { 00133 00134 // 00135 // Set the address of the exception to the current program address 00136 // and raise the exception by calling the exception dispatcher. 00137 // 00138 00139 ExceptionRecord.ExceptionAddress = (PVOID)(TrapFrame->Fir); 00140 KiDispatchException(&ExceptionRecord, 00141 ExceptionFrame, 00142 TrapFrame, 00143 UserMode, 00144 TRUE); 00145 } 00146 00147 return; 00148 } }

BOOLEAN KiInitMachineDependent VOID   ) 
 

Referenced by KeInitSystem().

VOID KiInitSystem VOID   ) 
 

Definition at line 96 of file kiinit.c.

References _KSERVICE_TABLE_DESCRIPTOR::Base, _KSERVICE_TABLE_DESCRIPTOR::Count, ExInitializeCallData(), FALSE, Index, KeBugCheckCallbackListHead, KeBugCheckCallbackLock, KeInitializeDpc(), KeInitializeEvent, KeInitializeSpinLock(), KeServiceDescriptorTable, KeServiceDescriptorTableShadow, KiArgumentTable, KiDispatcherReadyListHead, KiFlushSingleCallData, KiProcessInSwapListHead, KiProcessOutSwapListHead, KiProfileListHead, KiProfileLock, KiProfileSourceListHead, KiServiceLimit, KiServiceTable, KiSetEventCallData, KiStackInSwapListHead, KiSwapEvent, KiTimerExpiration(), KiTimerExpireDpc, KiTimerTableListHead, KiWaitInListHead, KiWaitOutListHead, KiWaitSingleCallData, _KSERVICE_TABLE_DESCRIPTOR::Limit, NIL, NULL, _KSERVICE_TABLE_DESCRIPTOR::Number, NUMBER_SERVICE_TABLES, PKDEFERRED_ROUTINE, and TIMER_TABLE_SIZE.

Referenced by KiInitializeKernel().

00102 : 00103 00104 This function initializes architecture independent kernel structures. 00105 00106 Arguments: 00107 00108 None. 00109 00110 Return Value: 00111 00112 None. 00113 00114 --*/ 00115 00116 { 00117 00118 ULONG Index; 00119 00120 // 00121 // Initialize dispatcher ready queue listheads. 00122 // 00123 00124 for (Index = 0; Index < MAXIMUM_PRIORITY; Index += 1) { 00125 InitializeListHead(&KiDispatcherReadyListHead[Index]); 00126 } 00127 00128 // 00129 // Initialize bug check callback listhead and spinlock. 00130 // 00131 00132 InitializeListHead(&KeBugCheckCallbackListHead); 00133 KeInitializeSpinLock(&KeBugCheckCallbackLock); 00134 00135 // 00136 // Initialize the timer expiration DPC object. 00137 // 00138 00139 KeInitializeDpc(&KiTimerExpireDpc, 00140 (PKDEFERRED_ROUTINE)KiTimerExpiration, NIL); 00141 00142 // 00143 // Initialize the profile listhead and profile locks 00144 // 00145 00146 KeInitializeSpinLock(&KiProfileLock); 00147 InitializeListHead(&KiProfileListHead); 00148 00149 // 00150 // Initialize the active profile source listhead. 00151 // 00152 00153 InitializeListHead(&KiProfileSourceListHead); 00154 00155 // 00156 // Initialize the timer table, the timer completion listhead, and the 00157 // timer completion DPC. 00158 // 00159 00160 for (Index = 0; Index < TIMER_TABLE_SIZE; Index += 1) { 00161 InitializeListHead(&KiTimerTableListHead[Index]); 00162 } 00163 00164 // 00165 // Initialize the swap event, the process inswap listhead, the 00166 // process outswap listhead, the kernel stack inswap listhead, 00167 // the wait in listhead, and the wait out listhead. 00168 // 00169 00170 KeInitializeEvent(&KiSwapEvent, 00171 SynchronizationEvent, 00172 FALSE); 00173 00174 InitializeListHead(&KiProcessInSwapListHead); 00175 InitializeListHead(&KiProcessOutSwapListHead); 00176 InitializeListHead(&KiStackInSwapListHead); 00177 InitializeListHead(&KiWaitInListHead); 00178 InitializeListHead(&KiWaitOutListHead); 00179 00180 // 00181 // Initialize the system service descriptor table. 00182 // 00183 00184 KeServiceDescriptorTable[0].Base = &KiServiceTable[0]; 00185 KeServiceDescriptorTable[0].Count = NULL; 00186 KeServiceDescriptorTable[0].Limit = KiServiceLimit; 00187 #if defined(_IA64_) 00188 00189 // 00190 // The global pointer associated with the table base is 00191 // placed just before the service table. 00192 // 00193 00194 KeServiceDescriptorTable[0].TableBaseGpOffset = 00195 (LONG)(*(KiServiceTable-1) - (ULONG_PTR)KiServiceTable); 00196 #endif 00197 KeServiceDescriptorTable[0].Number = &KiArgumentTable[0]; 00198 for (Index = 1; Index < NUMBER_SERVICE_TABLES; Index += 1) { 00199 KeServiceDescriptorTable[Index].Limit = 0; 00200 } 00201 00202 // 00203 // Copy the system service descriptor table to the shadow table 00204 // which is used to record the Win32 system services. 00205 // 00206 00207 RtlCopyMemory(KeServiceDescriptorTableShadow, 00208 KeServiceDescriptorTable, 00209 sizeof(KeServiceDescriptorTable)); 00210 00211 // 00212 // Initialize call performance data structures. 00213 // 00214 00215 #if defined(_COLLECT_FLUSH_SINGLE_CALLDATA_) 00216 00217 ExInitializeCallData(&KiFlushSingleCallData); 00218 00219 #endif 00220 00221 #if defined(_COLLECT_SET_EVENT_CALLDATA_) 00222 00223 ExInitializeCallData(&KiSetEventCallData); 00224 00225 #endif 00226 00227 #if defined(_COLLECT_WAIT_SINGLE_CALLDATA_) 00228 00229 ExInitializeCallData(&KiWaitSingleCallData); 00230 00231 #endif 00232 00233 return; 00234 }

LONG FASTCALL KiInsertQueue IN PRKQUEUE  Queue,
IN PLIST_ENTRY  Entry,
IN BOOLEAN  Head
 

Definition at line 710 of file queueobj.c.

References ASSERT_QUEUE, FALSE, _KTIMER::Header, _DISPATCHER_HEADER::Inserted, KeGetCurrentThread, KiReadyThread(), KiRemoveTreeTimer, _KTHREAD::Queue, _KWAIT_BLOCK::Thread, _KTHREAD::Timer, TRUE, _KTHREAD::WaitListEntry, _KTHREAD::WaitReason, _KTHREAD::WaitStatus, and WrQueue.

Referenced by KeInsertHeadQueue(), KeInsertQueue(), and KeTerminateThread().

00718 : 00719 00720 This function inserts the specified entry in the queue object entry 00721 list and attempts to satisfy the wait of a single waiter. 00722 00723 N.B. The wait discipline for Queue object is LIFO. 00724 00725 Arguments: 00726 00727 Queue - Supplies a pointer to a dispatcher object of type Queue. 00728 00729 Entry - Supplies a pointer to a list entry that is inserted in the 00730 queue object entry list. 00731 00732 Head - Supplies a boolean value that determines whether the queue 00733 entry is inserted at the head or tail of the queue if it can 00734 not be immediately dispatched. 00735 00736 Return Value: 00737 00738 The previous signal state of the Queue object. 00739 00740 --*/ 00741 00742 { 00743 00744 LONG OldState; 00745 PRKTHREAD Thread; 00746 PKTIMER Timer; 00747 PKWAIT_BLOCK WaitBlock; 00748 PLIST_ENTRY WaitEntry; 00749 00750 ASSERT_QUEUE(Queue); 00751 00752 // 00753 // Capture the current signal state of queue object and check if there 00754 // is a thread waiting on the queue object, the current number of active 00755 // threads is less than the target number of threads, and the wait reason 00756 // of the current thread is not queue wait or the wait queue is not the 00757 // same queue as the insertion queue. If these conditions are satisfied, 00758 // then satisfy the thread wait and pass the thread the address of the 00759 // queue entry as the wait status. Otherwise, set the state of the queue 00760 // object to signaled and insert the specified entry in the queue object 00761 // entry list. 00762 // 00763 00764 OldState = Queue->Header.SignalState; 00765 Thread = KeGetCurrentThread(); 00766 WaitEntry = Queue->Header.WaitListHead.Blink; 00767 if ((WaitEntry != &Queue->Header.WaitListHead) && 00768 (Queue->CurrentCount < Queue->MaximumCount) && 00769 ((Thread->Queue != Queue) || 00770 (Thread->WaitReason != WrQueue))) { 00771 00772 // 00773 // Remove the last wait block from the wait list and get the address 00774 // of the waiting thread object. 00775 // 00776 00777 RemoveEntryList(WaitEntry); 00778 WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry); 00779 Thread = WaitBlock->Thread; 00780 00781 // 00782 // Set the wait completion status, remove the thread from its wait 00783 // list, increment the number of active threads, and clear the wait 00784 // reason. 00785 // 00786 00787 Thread->WaitStatus = (LONG_PTR)Entry; 00788 RemoveEntryList(&Thread->WaitListEntry); 00789 Queue->CurrentCount += 1; 00790 Thread->WaitReason = 0; 00791 00792 // 00793 // If thread timer is still active, then cancel thread timer. 00794 // 00795 00796 Timer = &Thread->Timer; 00797 if (Timer->Header.Inserted == TRUE) { 00798 KiRemoveTreeTimer(Timer); 00799 } 00800 00801 // 00802 // Ready the thread for execution. 00803 // 00804 00805 KiReadyThread(Thread); 00806 00807 } else { 00808 Queue->Header.SignalState += 1; 00809 if (Head != FALSE) { 00810 InsertHeadList(&Queue->EntryListHead, Entry); 00811 00812 } else { 00813 InsertTailList(&Queue->EntryListHead, Entry); 00814 } 00815 } 00816 00817 return OldState; 00818 } }

BOOLEAN FASTCALL KiInsertQueueApc IN PKAPC  Apc,
IN KPRIORITY  Increment
 

Definition at line 223 of file apcsup.c.

References _KTHREAD::Alertable, _KAPC_STATE::ApcListHead, _KTHREAD::ApcQueueLock, _KTHREAD::ApcState, _KTHREAD::ApcStateIndex, _KTHREAD::ApcStatePointer, FALSE, Increment, _KTHREAD::KernelApcDisable, _KAPC_STATE::KernelApcInProgress, _KAPC_STATE::KernelApcPending, KernelMode, KiRequestApcInterrupt, KiUnwaitThread(), KPROCESSOR_MODE, _KTHREAD::NextProcessor, _KAPC::NormalRoutine, NULL, PsExitSpecialApc(), Running, _KTHREAD::State, TRUE, _KAPC_STATE::UserApcPending, UserMode, Waiting, _KTHREAD::WaitIrql, and _KTHREAD::WaitMode.

Referenced by Ke386VdmInsertQueueApc(), KeFreezeAllThreads(), KeInsertQueueApc(), and KeSuspendThread().

00230 : 00231 00232 This function inserts an APC object into a thread's APC queue. The address 00233 of the thread object, the APC queue, and the type of APC are all derived 00234 from the APC object. If the APC object is already in an APC queue, then 00235 no opertion is performed and a function value of FALSE is returned. Else 00236 the APC is inserted in the specified APC queue, its inserted state is set 00237 to TRUE, and a function value of TRUE is returned. The APC will actually 00238 be delivered when proper enabling conditions exist. 00239 00240 Arguments: 00241 00242 Apc - Supplies a pointer to a control object of type APC. 00243 00244 Increment - Supplies the priority increment that is to be applied if 00245 queuing the APC causes a thread wait to be satisfied. 00246 00247 Return Value: 00248 00249 If the APC object is already in an APC queue, then a value of FALSE is 00250 returned. Else a value of TRUE is returned. 00251 00252 --*/ 00253 00254 { 00255 00256 KPROCESSOR_MODE ApcMode; 00257 PKAPC ApcEntry; 00258 PKAPC_STATE ApcState; 00259 BOOLEAN Inserted; 00260 PLIST_ENTRY ListEntry; 00261 PKTHREAD Thread; 00262 00263 // 00264 // If the APC object is already in an APC queue, then set inserted to 00265 // FALSE. Else insert the APC object in the proper queue, set the APC 00266 // inserted state to TRUE, check to determine if the APC should be delivered 00267 // immediately, and set inserted to TRUE. 00268 // 00269 // For multiprocessor performance, the following code utilizes the fact 00270 // that kernel APC disable count is incremented before checking whether 00271 // the kernel APC queue is nonempty. 00272 // 00273 // See KeLeaveCriticalRegion(). 00274 // 00275 00276 Thread = Apc->Thread; 00277 KiAcquireSpinLock(&Thread->ApcQueueLock); 00278 if (Apc->Inserted) { 00279 Inserted = FALSE; 00280 00281 } else { 00282 ApcState = Thread->ApcStatePointer[Apc->ApcStateIndex]; 00283 00284 // 00285 // Insert the APC after all other special APC entries selected by 00286 // the processor mode if the normal routine value is null. Else 00287 // insert the APC object at the tail of the APC queue selected by 00288 // the processor mode unless the APC mode is user and the address 00289 // of the special APC routine is exit thread, in which case insert 00290 // the APC at the front of the list and set user APC pending. 00291 // 00292 00293 ApcMode = Apc->ApcMode; 00294 if (Apc->NormalRoutine != NULL) { 00295 if ((ApcMode != KernelMode) && (Apc->KernelRoutine == PsExitSpecialApc)) { 00296 Thread->ApcState.UserApcPending = TRUE; 00297 InsertHeadList(&ApcState->ApcListHead[ApcMode], 00298 &Apc->ApcListEntry); 00299 00300 } else { 00301 InsertTailList(&ApcState->ApcListHead[ApcMode], 00302 &Apc->ApcListEntry); 00303 } 00304 00305 } else { 00306 ListEntry = ApcState->ApcListHead[ApcMode].Flink; 00307 while (ListEntry != &ApcState->ApcListHead[ApcMode]) { 00308 ApcEntry = CONTAINING_RECORD(ListEntry, KAPC, ApcListEntry); 00309 if (ApcEntry->NormalRoutine != NULL) { 00310 break; 00311 } 00312 00313 ListEntry = ListEntry->Flink; 00314 } 00315 00316 ListEntry = ListEntry->Blink; 00317 InsertHeadList(ListEntry, &Apc->ApcListEntry); 00318 } 00319 00320 Apc->Inserted = TRUE; 00321 00322 // 00323 // If the APC index from the APC object matches the APC Index of 00324 // the thread, then check to determine if the APC should interrupt 00325 // thread execution or sequence the thread out of a wait state. 00326 // 00327 00328 if (Apc->ApcStateIndex == Thread->ApcStateIndex) { 00329 00330 // 00331 // If the processor mode of the APC is kernel, then check if 00332 // the APC should either interrupt the thread or sequence the 00333 // thread out of a Waiting state. Else check if the APC should 00334 // sequence the thread out of an alertable Waiting state. 00335 // 00336 00337 if (ApcMode == KernelMode) { 00338 Thread->ApcState.KernelApcPending = TRUE; 00339 if (Thread->State == Running) { 00340 KiRequestApcInterrupt(Thread->NextProcessor); 00341 00342 } else if ((Thread->State == Waiting) && 00343 (Thread->WaitIrql == 0) && 00344 ((Apc->NormalRoutine == NULL) || 00345 ((Thread->KernelApcDisable == 0) && 00346 (Thread->ApcState.KernelApcInProgress == FALSE)))) { 00347 KiUnwaitThread(Thread, STATUS_KERNEL_APC, Increment); 00348 } 00349 00350 } else if ((Thread->State == Waiting) && 00351 (Thread->WaitMode == UserMode) && 00352 (Thread->Alertable)) { 00353 Thread->ApcState.UserApcPending = TRUE; 00354 KiUnwaitThread(Thread, STATUS_USER_APC, Increment); 00355 } 00356 } 00357 00358 Inserted = TRUE; 00359 } 00360 00361 // 00362 // Unlock the APC queue lock, and return whether the APC object was 00363 // inserted in an APC queue. 00364 // 00365 00366 KiReleaseSpinLock(&Thread->ApcQueueLock); 00367 return Inserted; 00368 } }

LOGICAL FASTCALL KiInsertTreeTimer IN PRKTIMER  Timer,
IN LARGE_INTEGER  Interval
 

Definition at line 42 of file timersup.c.

References FALSE, KiInsertTimerTable(), and TRUE.

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeSetTimerEx(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), and KiTimerListExpire().

00049 : 00050 00051 This function inserts a timer object in the timer queue. 00052 00053 N.B. This routine assumes that the dispatcher data lock has been acquired. 00054 00055 Arguments: 00056 00057 Timer - Supplies a pointer to a dispatcher object of type timer. 00058 00059 Interval - Supplies the absolute or relative time at which the time 00060 is to expire. 00061 00062 Return Value: 00063 00064 If the timer is inserted in the timer tree, than a value of TRUE is 00065 returned. Otherwise, a value of FALSE is returned. 00066 00067 --*/ 00068 00069 { 00070 00071 LARGE_INTEGER CurrentTime; 00072 LARGE_INTEGER SystemTime; 00073 LARGE_INTEGER TimeDifference; 00074 00075 // 00076 // Clear the signal state of timer if the timer period is zero and set 00077 // the inserted state to TRUE. 00078 // 00079 00080 Timer->Header.Inserted = TRUE; 00081 Timer->Header.Absolute = FALSE; 00082 if (Timer->Period == 0) { 00083 Timer->Header.SignalState = FALSE; 00084 } 00085 00086 // 00087 // If the specified interval is not a relative time (i.e., is an absolute 00088 // time), then convert it to relative time. 00089 // 00090 00091 if (Interval.HighPart >= 0) { 00092 KiQuerySystemTime(&SystemTime); 00093 TimeDifference.QuadPart = SystemTime.QuadPart - Interval.QuadPart; 00094 00095 // 00096 // If the resultant relative time is greater than or equal to zero, 00097 // then the timer has already expired. 00098 // 00099 00100 if (TimeDifference.HighPart >= 0) { 00101 Timer->Header.SignalState = TRUE; 00102 Timer->Header.Inserted = FALSE; 00103 return FALSE; 00104 } 00105 00106 Interval = TimeDifference; 00107 Timer->Header.Absolute = TRUE; 00108 } 00109 00110 // 00111 // Get the current interrupt time, insert the timer in the timer table, 00112 // and return the inserted state. 00113 // 00114 00115 KiQueryInterruptTime(&CurrentTime); 00116 return KiInsertTimerTable(Interval, CurrentTime, Timer); 00117 }

VOID KiInterruptDispatch VOID   ) 
 

Referenced by KiGetVectorInfo().

VOID KiInterruptDispatchRaise IN PKINTERRUPT  Interrupt  ) 
 

Referenced by KeConnectInterrupt(), and KeDisconnectInterrupt().

VOID KiInterruptDispatchSame IN PKINTERRUPT  Interrupt  ) 
 

Referenced by KeConnectInterrupt(), and KeDisconnectInterrupt().

ULONG_PTR KiIpiGenericCall IN PKIPI_BROADCAST_WORKER  BroadcastFunction,
IN ULONG_PTR  Context
 

Definition at line 40 of file xipi.c.

References KeActiveProcessors, KeGetCurrentPrcb, KeLowerIrql(), KeRaiseIrql(), KiIpiGenericCallTarget(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), max, NULL, PKIPI_BROADCAST_WORKER, and Status.

Referenced by KeI386VdmInitialize(), KeSetIntervalProfile(), KiAdjustInterruptTime(), KiInitMachineDependent(), KiSyncMC_Drain(), and KiSyncPrefetchVisible().

00047 : 00048 00049 This function executes the specified function on every processor in 00050 the host configuration in a synchronous manner, i.e., the function 00051 is executed on each target in series with the execution of the source 00052 processor. 00053 00054 Arguments: 00055 00056 BroadcastFunction - Supplies the address of function that is executed 00057 on each of the target processors. 00058 00059 Context - Supplies the value of the context parameter that is passed 00060 to each function. 00061 00062 Return Value: 00063 00064 The value returned by the specified function on the source processor 00065 is returned as the function value. 00066 00067 --*/ 00068 00069 { 00070 00071 KIRQL OldIrql; 00072 ULONG_PTR Status; 00073 KAFFINITY TargetProcessors; 00074 00075 // 00076 // Raise IRQL to the higher of the current level and synchronization 00077 // level to avoid a possible context switch. 00078 // 00079 00080 KeRaiseIrql((KIRQL)(max(KiSynchIrql, KeGetCurrentIrql())), &OldIrql); 00081 00082 // 00083 // Initialize the broadcast packet, compute the set of target processors, 00084 // and sent the packet to the target processors for execution. 00085 // 00086 00087 #if !defined(NT_UP) 00088 00089 TargetProcessors = KeActiveProcessors & ~KeGetCurrentPrcb()->SetMember; 00090 if (TargetProcessors != 0) { 00091 KiIpiSendPacket(TargetProcessors, 00092 KiIpiGenericCallTarget, 00093 (PVOID)BroadcastFunction, 00094 (PVOID)Context, 00095 NULL); 00096 } 00097 00098 #endif 00099 00100 // 00101 // Execute function of source processor and capture return status. 00102 // 00103 00104 Status = BroadcastFunction(Context); 00105 00106 // 00107 // Wait until all of the target processors have finished capturing the 00108 // function parameters. 00109 // 00110 00111 #if !defined(NT_UP) 00112 00113 if (TargetProcessors != 0) { 00114 KiIpiStallOnPacketTargets(TargetProcessors); 00115 } 00116 00117 #endif 00118 00119 // 00120 // Lower IRQL to its previous level and return the function execution 00121 // status. 00122 // 00123 00124 KeLowerIrql(OldIrql); 00125 return Status; 00126 }

VOID FASTCALL KiIpiSend IN KAFFINITY  TargetProcessors,
IN KIPI_REQUEST  Request
 

Definition at line 253 of file mpipi.c.

References HalRequestIpi(), and KiProcessorBlock.

Referenced by KeBugCheckEx(), KeFreezeExecution(), KeInsertQueueDpc(), and KiReadyThread().

00260 : 00261 00262 This routine requests the specified operation on the target set of 00263 processors. 00264 00265 Arguments: 00266 00267 TargetProcessors (a0) - Supplies the set of processors on which the 00268 specified operation is to be executed. 00269 00270 IpiRequest (a1) - Supplies the request operation mask. 00271 00272 Return Value: 00273 00274 None. 00275 00276 --*/ 00277 00278 { 00279 #if !defined(NT_UP) 00280 ULONG RequestSummary; 00281 KAFFINITY NextProcessors; 00282 ULONG Next; 00283 00284 // 00285 // Loop through the target processors and send the packet to the specified 00286 // recipients. 00287 // 00288 00289 NextProcessors = TargetProcessors; 00290 Next = 0; 00291 00292 while (NextProcessors != 0) { 00293 00294 if ((NextProcessors & 1) != 0) { 00295 00296 do { 00297 00298 RequestSummary = KiProcessorBlock[Next]->RequestSummary; 00299 00300 } while(InterlockedCompareExchange( 00301 (PLONG) &KiProcessorBlock[Next]->RequestSummary, 00302 (LONG) (RequestSummary | IpiRequest), 00303 (LONG) RequestSummary) != (LONG) RequestSummary); 00304 } 00305 00306 NextProcessors = NextProcessors >> 1; 00307 00308 Next = Next + 1; 00309 00310 } 00311 HalRequestIpi (TargetProcessors); 00312 #endif 00313 00314 return; 00315 }

VOID KiIpiSendPacket IN KAFFINITY  TargetProcessors,
IN PKIPI_WORKER  WorkerFunction,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 

Definition at line 319 of file mpipi.c.

References HalRequestIpi(), KeGetCurrentPrcb, and KiProcessorBlock.

Referenced by Ke386IoSetAccessProcess(), Ke386SetIoAccessMap(), Ke386SetLdtProcess(), Ke386SetVdmInterruptHandler(), KeChangeColorPage(), KeDetachSessionSpace(), KeFlushEntireTb(), KeFlushIoBuffers(), KeFlushMultipleTb(), KeFlushMultipleTb64(), KeFlushSingleTb(), KeFlushSingleTb64(), KeStartProfile(), KeStopProfile(), KeSweepCacheRange(), KeSweepDcache(), KeSweepDcacheRange(), KeSweepIcache(), KeSweepIcacheRange(), KeSynchronizeMemoryAccess(), KiGetNewRid(), KiIpiGenericCall(), and KiSyncNewRegionId().

00329 : 00330 00331 This routine executes the specified worker function on the specified 00332 set of processors. 00333 00334 Arguments: 00335 00336 TargetProcessors (a0) - Supplies the set of processors on which the 00337 specified operation is to be executed. 00338 00339 WorkerFunction (a1) - Supplies the address of the worker function. 00340 00341 Parameter1 - Parameter3 (a2, a3, 4 * 4(sp)) - Supplies worker 00342 function specific parameters. 00343 00344 Return Value: 00345 00346 None. 00347 00348 --*/ 00349 { 00350 #if !defined(NT_UP) 00351 PKPRCB Prcb; 00352 KAFFINITY NextProcessors; 00353 ULONG Next; 00354 00355 Prcb = KeGetCurrentPrcb(); 00356 Prcb->TargetSet = TargetProcessors; 00357 Prcb->WorkerRoutine = WorkerFunction; 00358 Prcb->CurrentPacket[0] = Parameter1; 00359 Prcb->CurrentPacket[1] = Parameter2; 00360 Prcb->CurrentPacket[2] = Parameter3; 00361 00362 // 00363 // synchronize memory access 00364 // 00365 00366 __mf(); 00367 00368 // 00369 // Loop through the target processors and send the packet to the specified 00370 // recipients. 00371 // 00372 00373 NextProcessors = TargetProcessors; 00374 Next = 0; 00375 00376 while (NextProcessors != 0) { 00377 00378 if ((NextProcessors & 1) != 0) { 00379 00380 while(InterlockedCompareExchangePointer( 00381 (PVOID)&KiProcessorBlock[Next]->SignalDone, 00382 (PVOID)Prcb, 00383 (PVOID)0) != (PVOID)0); 00384 00385 } 00386 00387 NextProcessors = NextProcessors >> 1; 00388 00389 Next = Next + 1; 00390 00391 } 00392 HalRequestIpi (TargetProcessors); 00393 #endif 00394 }

BOOLEAN KiIpiServiceRoutine IN struct _KTRAP_FRAME *  TrapFrame,
IN struct _KEXCEPTION_FRAME *  ExceptionFrame
 

VOID FASTCALL KiIpiSignalPacketDone IN PKIPI_CONTEXT  SignalDone  ) 
 

Referenced by Ki386LoadTargetInt21Entry(), Ki386LoadTargetLdtr(), KiChangeColorPageTarget(), KiFlushEntireTbTarget(), KiFlushIoBuffersTarget(), KiFlushMultipleTbTarget(), KiFlushMultipleTbTarget64(), KiFlushSingleTbTarget(), KiFlushSingleTbTarget64(), KiFlushTargetEntireTb(), KiFlushTargetMultipleTb(), KiFlushTargetSingleTb(), KiIpiGenericCallTarget(), KiLoadIopmOffset(), KiSetIoMap(), KiStartProfileInterrupt(), KiStopProfileInterrupt(), KiSweepDcacheTarget(), KiSweepIcacheRangeTarget(), KiSweepIcacheTarget(), KiSyncCacheTarget(), KiSynchronizeMemoryAccessTarget(), KiSyncNewRegionIdTarget(), and KiSyncSessionTarget().

VOID KiIpiStallOnPacketTargets KAFFINITY  TargetSet  ) 
 

Definition at line 182 of file xipi.c.

References KeActiveProcessors, and KeGetCurrentPrcb.

Referenced by Ke386IoSetAccessProcess(), Ke386SetDescriptorProcess(), Ke386SetIoAccessMap(), Ke386SetLdtProcess(), Ke386SetVdmInterruptHandler(), KeChangeColorPage(), KeFlushEntireTb(), KeFlushIoBuffers(), KeFlushMultipleTb(), KeFlushMultipleTb64(), KeFlushSingleTb(), KeFlushSingleTb64(), KeInvalidateAllCaches(), KeStartProfile(), KeStopProfile(), KeSweepCacheRange(), KeSweepDcache(), KeSweepDcacheRange(), KeSweepIcache(), KeSweepIcacheRange(), KeSynchronizeMemoryAccess(), KiCompleteEffectiveRangeChange(), KiFlushSingleTbSynchronous(), KiGetNewRid(), KiInitializePAT(), KiIpiGenericCall(), and KiSyncNewRegionId().

00188 : 00189 00190 This function waits until the specified set of processors have signaled 00191 their completion of a requested function. 00192 00193 N.B. The exact protocol used between the source and the target of an 00194 interprocessor request is not specified. Minimally the source 00195 must construct an appropriate packet and send the packet to a set 00196 of specified targets. Each target receives the address of the packet 00197 address as an argument, and minimally must clear the packet address 00198 when the mutually agreed upon protocol allows. The target has three 00199 options: 00200 00201 1. Capture necessary information, release the source by clearing 00202 the packet address, execute the request in parallel with the 00203 source, and return from the interrupt. 00204 00205 2. Execute the request in series with the source, release the 00206 source by clearing the packet address, and return from the 00207 interrupt. 00208 00209 3. Execute the request in series with the source, release the 00210 source, wait for a reply from the source based on a packet 00211 parameter, and return from the interrupt. 00212 00213 This function is provided to enable the source to synchronize with the 00214 target for cases 2 and 3 above. 00215 00216 N.B. There is no support for method 3 above. 00217 00218 Arguments: 00219 00220 TargetSet - Supplies the the target set of IPI processors. 00221 00222 Return Value: 00223 00224 None. 00225 00226 --*/ 00227 00228 { 00229 00230 PKPRCB Prcb; 00231 00232 // 00233 // Wait until the target set of processors is zero in the current 00234 // processor's packet. 00235 // 00236 00237 Prcb = KeGetCurrentPrcb(); 00238 while (Prcb->TargetSet != 0) { 00239 KeYieldProcessor(); 00240 } 00241 00242 // 00243 // If the target set is equal to the entire set of processors, then 00244 // update the memory barrier time stamp. 00245 // 00246 00247 #if defined(_ALPHA_) 00248 00249 if ((TargetSet | PCR->SetMember ) == KeActiveProcessors) { 00250 InterlockedIncrement(&KiMbTimeStamp); 00251 } 00252 00253 #endif 00254 00255 return; 00256 }

KIRQL KiLockDeviceQueue IN PKDEVICE_QUEUE  DeviceQueue  ) 
 

VOID KiPassiveRelease VOID   ) 
 

Referenced by KiInitializeKernel().

VOID KiPollFreezeExecution VOID   ) 
 

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

References IPI_FREEZE, KeGetCurrentPrcb, KiFreezeTargetExecution(), and NULL.

Referenced by KiCalibrateTimeAdjustment().

00544 : 00545 00546 This routine is called from code that is spinning with interrupts 00547 disabled, waiting for something to happen, when there is some 00548 (possibly extremely small) chance that that thing will not happen 00549 because a system freeze has been initiated. 00550 00551 N.B. Interrupts are disabled. 00552 00553 Arguments: 00554 00555 None. 00556 00557 Return Value: 00558 00559 None. 00560 00561 --*/ 00562 00563 { 00564 // 00565 // Check to see if a freeze is pending for this processor. 00566 // 00567 00568 PKPRCB Prcb = KeGetCurrentPrcb(); 00569 00570 if ((Prcb->RequestSummary & IPI_FREEZE) != 0) { 00571 00572 // 00573 // Clear the freeze request and freeze this processor. 00574 // 00575 00576 InterlockedExchangeAdd((PLONG)&Prcb->RequestSummary, -(IPI_FREEZE)); 00577 KiFreezeTargetExecution(NULL, NULL); 00578 00579 } else { 00580 00581 // 00582 // No freeze pending, assume this processor is spinning. 00583 // 00584 00585 KeYieldProcessor(); 00586 } 00587 } }

NTSTATUS KiRaiseException IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN BOOLEAN  FirstChance
 

Definition at line 208 of file raisexcp.c.

References EXCEPTION_EXECUTE_HANDLER, KeContextToKframes(), KernelMode, KiDispatchException(), KPROCESSOR_MODE, and ProbeForRead.

00218 : 00219 00220 This function is called to raise an exception. The exception can be 00221 raised as a first or second chance exception. 00222 00223 Arguments: 00224 00225 ExceptionRecord - Supplies a pointer to an exception record. 00226 00227 ContextRecord - Supplies a pointer to a context record. 00228 00229 ExceptionFrame - Supplies a pointer to an exception frame. 00230 00231 TrapFrame - Supplies a pointer to a trap frame. 00232 00233 FirstChance - Supplies a boolean value that specifies whether this is 00234 the first (TRUE) or second (FALSE) chance for the exception. 00235 00236 Return Value: 00237 00238 STATUS_ACCESS_VIOLATION is returned if either the exception or the context 00239 record is not readable from user mode. 00240 00241 STATUS_DATATYPE_MISALIGNMENT is returned if the exception record or the 00242 context record are not properly aligned. 00243 00244 STATUS_INVALID_PARAMETER is returned if the number of exception parameters 00245 is greater than the maximum allowable number of exception parameters. 00246 00247 STATUS_SUCCESS is returned if the exception is dispatched and handled. 00248 00249 --*/ 00250 00251 { 00252 00253 CONTEXT ContextRecord2; 00254 EXCEPTION_RECORD ExceptionRecord2; 00255 ULONG Length; 00256 ULONG Params; 00257 KPROCESSOR_MODE PreviousMode; 00258 00259 // 00260 // Establish an exception handler and probe the specified exception and 00261 // context records for read accessibility. If the probe fails, then 00262 // return the exception code as the service status. Else call the exception 00263 // dispatcher to dispatch the exception. 00264 // 00265 00266 try { 00267 00268 // 00269 // Get the previous processor mode. If the previous processor mode 00270 // is user, then probe and copy the specified exception and context 00271 // records. 00272 // 00273 00274 PreviousMode = KeGetPreviousMode(); 00275 if (PreviousMode != KernelMode) { 00276 ProbeForRead(ContextRecord, sizeof(CONTEXT), CONTEXT_ALIGN); 00277 ProbeForRead(ExceptionRecord, 00278 FIELD_OFFSET (EXCEPTION_RECORD, NumberParameters) + 00279 sizeof (ExceptionRecord->NumberParameters), sizeof(ULONG)); 00280 Params = ExceptionRecord->NumberParameters; 00281 if (Params > EXCEPTION_MAXIMUM_PARAMETERS) { 00282 return STATUS_INVALID_PARAMETER; 00283 } 00284 00285 // 00286 // The exception record structure is defined unlike others with trailing 00287 // information as being its maximum size rather than just a single trailing 00288 // element. 00289 // 00290 Length = (sizeof(EXCEPTION_RECORD) - 00291 ((EXCEPTION_MAXIMUM_PARAMETERS - Params) * 00292 sizeof(ExceptionRecord->ExceptionInformation[0]))); 00293 00294 // 00295 // The structure is currently less that 64k so we don't really need this probe. 00296 // 00297 ProbeForRead(ExceptionRecord, Length, sizeof(ULONG)); 00298 00299 // 00300 // Copy the exception and context record to local storage so an 00301 // access violation cannot occur during exception dispatching. 00302 // 00303 00304 RtlMoveMemory(&ContextRecord2, ContextRecord, sizeof(CONTEXT)); 00305 RtlMoveMemory(&ExceptionRecord2, ExceptionRecord, Length); 00306 ContextRecord = &ContextRecord2; 00307 ExceptionRecord = &ExceptionRecord2; 00308 // 00309 // The number of parameters might have changed after we validated but before we 00310 // copied the structure. Fix this up as lower levels might not like this. 00311 // 00312 ExceptionRecord->NumberParameters = Params; 00313 } 00314 00315 // 00316 // If an exception occurs during the probe of the exception or context 00317 // record, then always handle the exception and return the exception code 00318 // as the status value. 00319 // 00320 00321 } except(EXCEPTION_EXECUTE_HANDLER) { 00322 return GetExceptionCode(); 00323 } 00324 00325 // 00326 // Move information from the context record to the exception and 00327 // trap frames. 00328 // 00329 00330 KeContextToKframes(TrapFrame, 00331 ExceptionFrame, 00332 ContextRecord, 00333 ContextRecord->ContextFlags, 00334 PreviousMode); 00335 00336 // 00337 // Make sure the reserved bit is clear in the exception code and 00338 // perform exception dispatching. 00339 // 00340 // N.B. The reserved bit is used to differentiate internally gerarated 00341 // codes from codes generated by application programs. 00342 // 00343 00344 ExceptionRecord->ExceptionCode &= 0xefffffff; 00345 KiDispatchException(ExceptionRecord, 00346 ExceptionFrame, 00347 TrapFrame, 00348 PreviousMode, 00349 FirstChance); 00350 00351 return STATUS_SUCCESS; 00352 } }

VOID FASTCALL KiReadyThread IN PRKTHREAD  Thread  ) 
 

Definition at line 270 of file thredsup.c.

References BALANCE_INCREMENT, ClearMember, FALSE, FASTCALL, FindFirstSetLeftMember, _KEVENT::Header, IPI_DPC, KeGetCurrentPrcb, KiDispatcherReadyListHead, KiIdleSummary, KiIncrementSwitchCounter, KiIpiSend(), KiProcessInSwapListHead, KiProcessorBlock, KiReadySummary, KiRequestDispatchInterrupt, KiStackInSwapListHead, KiSwapEvent, KiWaitTest(), NULL, PoSleepingSummary, _KTHREAD::Preempted, _KTHREAD::Priority, ProcessInMemory, ProcessInTransition, ProcessOutOfMemory, Ready, _KPROCESS::ReadyListHead, SetMember, _DISPATCHER_HEADER::SignalState, _KPROCESS::StackCount, Standby, _KPROCESS::State, _KPROCESS::SwapListEntry, Transition, TRUE, and _DISPATCHER_HEADER::WaitListHead.

Referenced by KeDelayExecutionThread(), KeReadyThread(), KeSetAffinityThread(), KiAttachProcess(), KiInsertQueue(), KiInSwapKernelStacks(), KiInSwapProcesses(), KiOutSwapProcesses(), KiScanReadyQueues(), KiSetPriorityThread(), KiUnwaitThread(), NtReplyWaitSendChannel(), and NtSendWaitReplyChannel().

00276 : 00277 00278 This function readies a thread for execution and attempts to immediately 00279 dispatch the thread for execution by preempting another lower priority 00280 thread. If a thread can be preempted, then the specified thread enters 00281 the standby state and the target processor is requested to dispatch. If 00282 another thread cannot be preempted, then the specified thread is inserted 00283 either at the head or tail of the dispatcher ready selected by its priority 00284 acccording to whether it was preempted or not. 00285 00286 Arguments: 00287 00288 Thread - Supplies a pointer to a dispatcher object of type thread. 00289 00290 Return Value: 00291 00292 None. 00293 00294 --*/ 00295 00296 { 00297 00298 PRKPRCB Prcb; 00299 BOOLEAN Preempted; 00300 KPRIORITY Priority; 00301 PRKPROCESS Process; 00302 ULONG Processor; 00303 KPRIORITY ThreadPriority; 00304 PRKTHREAD Thread1; 00305 KAFFINITY IdleSet; 00306 00307 // 00308 // Save value of thread's preempted flag, set thread preempted FALSE, 00309 // capture the thread priority, and set clear the read wait time. 00310 // 00311 00312 Preempted = Thread->Preempted; 00313 Thread->Preempted = FALSE; 00314 ThreadPriority = Thread->Priority; 00315 Thread->WaitTime = KiQueryLowTickCount(); 00316 00317 // 00318 // If the thread's process is not in memory, then insert the thread in 00319 // the process ready queue and inswap the process. 00320 // 00321 00322 Process = Thread->ApcState.Process; 00323 if (Process->State != ProcessInMemory) { 00324 Thread->State = Ready; 00325 Thread->ProcessReadyQueue = TRUE; 00326 InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry); 00327 if (Process->State == ProcessOutOfMemory) { 00328 Process->State = ProcessInTransition; 00329 InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry); 00330 KiSwapEvent.Header.SignalState = 1; 00331 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00332 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00333 } 00334 } 00335 00336 return; 00337 00338 } else if (Thread->KernelStackResident == FALSE) { 00339 00340 // 00341 // The thread's kernel stack is not resident. Increment the process 00342 // stack count, set the state of the thread to transition, insert 00343 // the thread in the kernel stack inswap list, and set the kernel 00344 // stack inswap event. 00345 // 00346 00347 Process->StackCount += 1; 00348 Thread->State = Transition; 00349 InsertTailList(&KiStackInSwapListHead, &Thread->WaitListEntry); 00350 KiSwapEvent.Header.SignalState = 1; 00351 if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) { 00352 KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT); 00353 } 00354 00355 return; 00356 00357 } else { 00358 00359 // 00360 // If there is an idle processor, then schedule the thread on an 00361 // idle processor giving preference to the processor the thread 00362 // last ran on. Otherwise, try to preempt either a thread in the 00363 // standby or running state. 00364 // 00365 00366 #if defined(NT_UP) 00367 00368 Prcb = KiProcessorBlock[0]; 00369 if (KiIdleSummary != 0) { 00370 KiIdleSummary = 0; 00371 KiIncrementSwitchCounter(IdleLast); 00372 Prcb->NextThread = Thread; 00373 Thread->State = Standby; 00374 00375 #else 00376 00377 IdleSet = KiIdleSummary & Thread->Affinity; 00378 if (IdleSet != 0) { 00379 Prcb = KeGetCurrentPrcb(); 00380 Processor = Thread->IdealProcessor; 00381 if ((IdleSet & (1 << Processor)) == 0) { 00382 Processor = Thread->NextProcessor; 00383 if ((IdleSet & (1 << Processor)) == 0) { 00384 if ((IdleSet & Prcb->SetMember) == 0) { 00385 FindFirstSetLeftMember(IdleSet, &Processor); 00386 KiIncrementSwitchCounter(IdleAny); 00387 00388 } else { 00389 Processor = Prcb->Number; 00390 KiIncrementSwitchCounter(IdleCurrent); 00391 } 00392 00393 } else { 00394 KiIncrementSwitchCounter(IdleLast); 00395 } 00396 00397 } else { 00398 KiIncrementSwitchCounter(IdleIdeal); 00399 } 00400 00401 Thread->NextProcessor = (CCHAR)Processor; 00402 ClearMember(Processor, KiIdleSummary); 00403 KiProcessorBlock[Processor]->NextThread = Thread; 00404 Thread->State = Standby; 00405 00406 if ((PoSleepingSummary & (1 << Processor)) && 00407 Processor != (ULONG) Prcb->Number) { 00408 KiIpiSend(1 << Processor, IPI_DPC); 00409 } 00410 #endif 00411 00412 return; 00413 00414 } else { 00415 00416 #if !defined(NT_UP) 00417 00418 Processor = Thread->IdealProcessor; 00419 if ((Thread->Affinity & (1 << Processor)) == 0) { 00420 Processor = Thread->NextProcessor; 00421 if ((Thread->Affinity & (1 << Processor)) == 0) { 00422 FindFirstSetLeftMember(Thread->Affinity, &Processor); 00423 } 00424 } 00425 00426 Thread->NextProcessor = (CCHAR)Processor; 00427 Prcb = KiProcessorBlock[Processor]; 00428 00429 #endif 00430 00431 if (Prcb->NextThread != NULL) { 00432 Thread1 = Prcb->NextThread; 00433 if (ThreadPriority > Thread1->Priority) { 00434 Thread1->Preempted = TRUE; 00435 Prcb->NextThread = Thread; 00436 Thread->State = Standby; 00437 KiReadyThread(Thread1); 00438 KiIncrementSwitchCounter(PreemptLast); 00439 return; 00440 } 00441 00442 } else { 00443 Thread1 = Prcb->CurrentThread; 00444 if (ThreadPriority > Thread1->Priority) { 00445 Thread1->Preempted = TRUE; 00446 Prcb->NextThread = Thread; 00447 Thread->State = Standby; 00448 KiRequestDispatchInterrupt(Thread->NextProcessor); 00449 KiIncrementSwitchCounter(PreemptLast); 00450 return; 00451 } 00452 } 00453 } 00454 } 00455 00456 // 00457 // No thread can be preempted. Insert the thread in the dispatcher 00458 // queue selected by its priority. If the thread was preempted and 00459 // runs at a realtime priority level, then insert the thread at the 00460 // front of the queue. Else insert the thread at the tail of the queue. 00461 // 00462 00463 Thread->State = Ready; 00464 if (Preempted != FALSE) { 00465 InsertHeadList(&KiDispatcherReadyListHead[ThreadPriority], 00466 &Thread->WaitListEntry); 00467 00468 } else { 00469 InsertTailList(&KiDispatcherReadyListHead[ThreadPriority], 00470 &Thread->WaitListEntry); 00471 } 00472 00473 SetMember(ThreadPriority, KiReadySummary); 00474 return; 00475 }

LOGICAL FASTCALL KiReinsertTreeTimer IN PRKTIMER  Timer,
IN ULARGE_INTEGER  DueTime
 

Definition at line 121 of file timersup.c.

References FALSE, KiInsertTimerTable(), and TRUE.

Referenced by KeSetSystemTime().

00128 : 00129 00130 This function reinserts a timer object in the timer queue. 00131 00132 N.B. This routine assumes that the dispatcher data lock has been acquired. 00133 00134 Arguments: 00135 00136 Timer - Supplies a pointer to a dispatcher object of type timer. 00137 00138 DueTime - Supplies the absolute time the timer is to expire. 00139 00140 Return Value: 00141 00142 If the timer is inserted in the timer tree, than a value of TRUE is 00143 returned. Otherwise, a value of FALSE is returned. 00144 00145 --*/ 00146 00147 { 00148 00149 LARGE_INTEGER CurrentTime; 00150 LARGE_INTEGER Interval; 00151 00152 // 00153 // Clear the signal state of timer if the timer period is zero and set 00154 // the inserted state to TRUE. 00155 // 00156 00157 Timer->Header.Inserted = TRUE; 00158 if (Timer->Period == 0) { 00159 Timer->Header.SignalState = FALSE; 00160 } 00161 00162 // 00163 // Compute the interval between the current time and the due time. 00164 // If the resultant relative time is greater than or equal to zero, 00165 // then the timer has already expired. 00166 // 00167 00168 KiQueryInterruptTime(&CurrentTime); 00169 Interval.QuadPart = CurrentTime.QuadPart - DueTime.QuadPart; 00170 if (Interval.QuadPart >= 0) { 00171 Timer->Header.SignalState = TRUE; 00172 Timer->Header.Inserted = FALSE; 00173 return FALSE; 00174 } 00175 00176 // 00177 // Insert the timer in the timer table and return the inserted state. 00178 // 00179 00180 return KiInsertTimerTable(Interval, CurrentTime, Timer); 00181 }

VOID KiRestoreInterrupts IN BOOLEAN  Enable  ) 
 

Referenced by KdPollBreakIn(), KeFreezeExecution(), KeThawExecution(), KiCalibrateTimeAdjustment(), KiCheckForSoftwareInterrupt(), KiFreezeTargetExecution(), KiI386PentiumLockErrataFixup(), KiLoadMTRR(), and KiLoadPAT().

VOID KiRestoreProcessorControlState IN PKPROCESSOR_STATE  ProcessorState  ) 
 

VOID KiRestoreProcessorState IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 31 of file alpha/ipi.c.

References CONTEXT_FULL, KeContextToKframes(), KeGetCurrentPrcb, KernelMode, and KiRestoreProcessorControlState().

Referenced by KdpTrap(), and KiFreezeTargetExecution().

00038 : 00039 00040 This function moves processor register state from the current 00041 processor context structure in the processor block to the 00042 specified trap and exception frames. 00043 00044 Arguments: 00045 00046 TrapFrame - Supplies a pointer to a trap frame. 00047 00048 ExceptionFrame - Supplies a pointer to an exception frame. 00049 00050 Return Value: 00051 00052 None. 00053 00054 --*/ 00055 00056 { 00057 00058 PKPRCB Prcb; 00059 00060 // 00061 // Get the address of the current processor block and move the 00062 // specified register state from the processor context structure 00063 // to the specified trap and exception frames 00064 // 00065 00066 #if !defined(NT_UP) 00067 00068 Prcb = KeGetCurrentPrcb(); 00069 KeContextToKframes(TrapFrame, 00070 ExceptionFrame, 00071 &Prcb->ProcessorState.ContextFrame, 00072 CONTEXT_FULL, 00073 KernelMode); 00074 00075 #endif 00076 00077 return; 00078 }

VOID KiRundownChannel VOID   ) 
 

Referenced by KeRundownThread().

VOID KiSaveProcessorControlState IN PKPROCESSOR_STATE  ProcessorState  ) 
 

Definition at line 124 of file xxmpipi.c.

00130 : 00131 00132 This routine saves the processor's control state for debugger. 00133 00134 Arguments: 00135 00136 ProcessorState (a0) - Supplies a pointer to the processor state. 00137 00138 Return Value: 00139 00140 None. 00141 00142 --*/ 00143 00144 { 00145 00146 ULONG Index; 00147 00148 // 00149 // Read Tb entries and store in the processor state structure. 00150 // 00151 00152 for (Index = 0; Index < KeNumberTbEntries; Index += 1) { 00153 KiReadEntryTb(Index, &ProcessorState->TbEntry[Index]); 00154 } 00155 00156 return; 00157 }

VOID KiSaveProcessorState IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 81 of file alpha/ipi.c.

References CONTEXT_FULL, KeContextFromKframes(), KeGetCurrentPrcb, and KiSaveProcessorControlState().

Referenced by KdpTrap(), and KiFreezeTargetExecution().

00088 : 00089 00090 This function moves processor register state from the specified trap 00091 and exception frames to the processor context structure in the current 00092 processor block. 00093 00094 Arguments: 00095 00096 TrapFrame - Supplies a pointer to a trap frame. 00097 00098 ExceptionFrame - Supplies a pointer to an exception frame. 00099 00100 Return Value: 00101 00102 None. 00103 00104 --*/ 00105 00106 { 00107 00108 PKPRCB Prcb; 00109 00110 // 00111 // Get the address of the current processor block and move the 00112 // specified register state from specified trap and exception 00113 // frames to the current processor context structure. 00114 // 00115 00116 #if !defined(NT_UP) 00117 00118 Prcb = KeGetCurrentPrcb(); 00119 Prcb->ProcessorState.ContextFrame.ContextFlags = CONTEXT_FULL; 00120 KeContextFromKframes(TrapFrame, 00121 ExceptionFrame, 00122 &Prcb->ProcessorState.ContextFrame); 00123 00124 #endif 00125 00126 return; 00127 }

PRKTHREAD FASTCALL KiSelectNextThread IN PRKTHREAD  Thread  ) 
 

Definition at line 479 of file thredsup.c.

References KiFindReadyThread(), KiIdleSummary, KiIncrementSwitchCounter, KiProcessorBlock, _KTHREAD::NextProcessor, NULL, and SetMember.

Referenced by KeRevertToUserAffinityThread(), KeSetAffinityThread(), and KeSetSystemAffinityThread().

00485 : 00486 00487 This function selects the next thread to run on the processor that the 00488 specified thread is running on. If a thread cannot be found, then the 00489 idle thread is selected. 00490 00491 Arguments: 00492 00493 Thread - Supplies a pointer to a dispatcher object of type thread. 00494 00495 Return Value: 00496 00497 The address of the selected thread object. 00498 00499 --*/ 00500 00501 { 00502 00503 PRKPRCB Prcb; 00504 ULONG Processor; 00505 PRKTHREAD Thread1; 00506 00507 // 00508 // Get the processor number and the address of the processor control block. 00509 // 00510 00511 #if !defined(NT_UP) 00512 00513 Processor = Thread->NextProcessor; 00514 Prcb = KiProcessorBlock[Processor]; 00515 00516 #else 00517 00518 Prcb = KiProcessorBlock[0]; 00519 00520 #endif 00521 00522 // 00523 // If a thread has already been selected to run on the specified processor, 00524 // then return that thread as the selected thread. 00525 // 00526 00527 if ((Thread1 = Prcb->NextThread) != NULL) { 00528 Prcb->NextThread = (PKTHREAD)NULL; 00529 00530 } else { 00531 00532 // 00533 // Attempt to find a ready thread to run. 00534 // 00535 00536 #if !defined(NT_UP) 00537 00538 Thread1 = KiFindReadyThread(Processor, 0); 00539 00540 #else 00541 00542 Thread1 = KiFindReadyThread(0, 0); 00543 00544 #endif 00545 00546 // 00547 // If a thread was not found, then select the idle thread and 00548 // set the processor member in the idle summary. 00549 // 00550 00551 if (Thread1 == NULL) { 00552 KiIncrementSwitchCounter(SwitchToIdle); 00553 Thread1 = Prcb->IdleThread; 00554 00555 #if !defined(NT_UP) 00556 00557 SetMember(Processor, KiIdleSummary); 00558 00559 #else 00560 KiIdleSummary = 1; 00561 00562 #endif 00563 00564 } 00565 } 00566 00567 // 00568 // Return address of selected thread object. 00569 // 00570 00571 return Thread1; 00572 }

KCONTINUE_STATUS KiSetDebugProcessor IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN KPROCESSOR_MODE  PreviousMode
 

VOID KiSetSystemTime IN PLARGE_INTEGER  NewTime,
OUT PLARGE_INTEGER  OldTime
 

VOID KiSuspendNop IN struct _KAPC Apc,
IN OUT PKNORMAL_ROUTINE NormalRoutine,
IN OUT PVOID *  NormalContext,
IN OUT PVOID *  SystemArgument1,
IN OUT PVOID *  SystemArgument2
 

Referenced by KeInitializeThread().

VOID KiSuspendThread IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 770 of file thredsup.c.

References _KAPC_STATE::ApcListHead, _KTHREAD::ApcState, FALSE, KeGetCurrentThread, KernelMode, _KAPC::KernelRoutine, KeWaitForSingleObject(), NULL, PsExitSpecialApc(), Suspended, _KTHREAD::SuspendSemaphore, _KAPC_STATE::UserApcPending, and UserMode.

Referenced by KeInitializeThread().

00778 : 00779 00780 This function is the kernel routine for the builtin suspend APC of a 00781 thread. It is executed in kernel mode as the result of queuing the builtin 00782 suspend APC and suspends thread execution by Waiting nonalerable on the 00783 thread's builtin suspend semaphore. When the thread is resumed, execution 00784 of thread is continued by simply returning. 00785 00786 Arguments: 00787 00788 Apc - Supplies a pointer to a control object of type APC. 00789 00790 Return Value: 00791 00792 None. 00793 00794 --*/ 00795 00796 { 00797 00798 PRKTHREAD Thread; 00799 PKAPC Apc; 00800 00801 // 00802 // Get the address of the current thread object and Wait nonalertable on 00803 // the thread's builtin suspend semaphore. 00804 // 00805 00806 Thread = KeGetCurrentThread(); 00807 00808 // 00809 // See if the thread is exiting. If the thread has the user-mode exit 00810 // APC in it's queue, KeForceResumeThread has been called, but it might 00811 // have been called just before KeSuspendThread. Account for the race here 00812 // by testing for the exit APC. During exit, we queue the user-mode exit APC 00813 // and set UserApcPending from the kernel-mode exit APC, then we call 00814 // KeForceResumeThread. 00815 // 00816 00817 if ( Thread->ApcState.UserApcPending ) { 00818 Apc = CONTAINING_RECORD((Thread->ApcState.ApcListHead[UserMode].Flink), KAPC, ApcListEntry); 00819 if ( Apc->KernelRoutine == PsExitSpecialApc ) { 00820 return; 00821 } 00822 } 00823 KeWaitForSingleObject(&Thread->SuspendSemaphore, 00824 Suspended, 00825 KernelMode, 00826 FALSE, 00827 (PLARGE_INTEGER)NULL); 00828 00829 } #if 0

BOOLEAN KiSwapProcess IN PKPROCESS  NewProcess,
IN PKPROCESS  OldProcess
 

Referenced by KeDetachProcess(), KeUnstackDetachProcess(), and KiAttachProcess().

LONG_PTR FASTCALL KiSwapThread VOID   ) 
 

Referenced by KeDelayExecutionThread(), KeRemoveQueue(), KeTerminateThread(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), KiAttachProcess(), and NtYieldExecution().

VOID KiThreadStartup IN PVOID  StartContext  ) 
 

Referenced by KiInitializeContextThread().

VOID KiTimerExpiration IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2
 

Definition at line 217 of file dpcsup.c.

References _KTIMER::DueTime, Index, KeNumberProcessors, KiLockDispatcherDatabase, KiTimerListExpire(), KiTimerTableListHead, TIMER_TABLE_SIZE, and _KTIMER::TimerListEntry.

Referenced by KiInitSystem().

00226 : 00227 00228 This function is called when the clock interupt routine discovers that 00229 a timer has expired. 00230 00231 Arguments: 00232 00233 TimerDpc - Supplies a pointer to a control object of type DPC. 00234 00235 DeferredContext - Not used. 00236 00237 SystemArgument1 - Supplies the starting timer table index value to 00238 use for the timer table scan. 00239 00240 SystemArgument2 - Not used. 00241 00242 Return Value: 00243 00244 None. 00245 00246 --*/ 00247 00248 { 00249 ULARGE_INTEGER CurrentTime; 00250 LIST_ENTRY ExpiredListHead; 00251 LONG HandLimit; 00252 LONG Index; 00253 PLIST_ENTRY ListHead; 00254 PLIST_ENTRY NextEntry; 00255 KIRQL OldIrql; 00256 PKTIMER Timer; 00257 00258 // 00259 // Acquire the dispatcher database lock and read the current interrupt 00260 // time to determine which timers have expired. 00261 // 00262 00263 KiLockDispatcherDatabase(&OldIrql); 00264 KiQueryInterruptTime((PLARGE_INTEGER)&CurrentTime); 00265 00266 // 00267 // If the timer table has not wrapped, then start with the specified 00268 // timer table index value, and scan for timer entries that have expired. 00269 // Otherwise, start with the first entry in the timer table and scan the 00270 // entire table for timer entries that have expired. 00271 // 00272 // N.B. This later condition exists when DPC processing is blocked for a 00273 // period longer than one round trip throught the timer table. 00274 // 00275 00276 HandLimit = (LONG)KiQueryLowTickCount(); 00277 if (((ULONG)(HandLimit - PtrToLong(SystemArgument1))) >= TIMER_TABLE_SIZE) { 00278 Index = - 1; 00279 HandLimit = TIMER_TABLE_SIZE - 1; 00280 00281 } else { 00282 Index = (PtrToLong(SystemArgument1) - 1) & (TIMER_TABLE_SIZE - 1); 00283 HandLimit &= (TIMER_TABLE_SIZE - 1); 00284 } 00285 00286 InitializeListHead(&ExpiredListHead); 00287 do { 00288 Index = (Index + 1) & (TIMER_TABLE_SIZE - 1); 00289 ListHead = &KiTimerTableListHead[Index]; 00290 NextEntry = ListHead->Flink; 00291 while (NextEntry != ListHead) { 00292 Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry); 00293 if (Timer->DueTime.QuadPart <= CurrentTime.QuadPart) { 00294 00295 // 00296 // The next timer in the current timer list has expired. 00297 // Remove the entry from the timer list and insert the 00298 // timer in the expired list. 00299 // 00300 00301 RemoveEntryList(&Timer->TimerListEntry); 00302 InsertTailList(&ExpiredListHead, &Timer->TimerListEntry); 00303 NextEntry = ListHead->Flink; 00304 00305 } else { 00306 break; 00307 } 00308 } 00309 00310 } while(Index != HandLimit); 00311 00312 #if DBG 00313 00314 if ((PtrToUlong(SystemArgument2) == 0) && (KeNumberProcessors == 1)) { 00315 KiCheckTimerTable(CurrentTime); 00316 } 00317 00318 #endif 00319 00320 // 00321 // Process the expired timer list. 00322 // 00323 // N.B. The following function returns with the dispatcher database 00324 // unlocked. 00325 // 00326 00327 KiTimerListExpire(&ExpiredListHead, OldIrql); 00328 return; 00329 }

VOID FASTCALL KiTimerListExpire IN PLIST_ENTRY  ExpiredListHead,
IN KIRQL  OldIrql
 

Definition at line 333 of file dpcsup.c.

References _DPC_ENTRY::Context, Count, _KDPC::DeferredContext, _KDPC::DeferredRoutine, DISPATCH_LEVEL, _DPC_ENTRY::Dpc, _KTIMER::Dpc, FALSE, _KTIMER::Header, Index, KeGetCurrentPrcb, KeInsertQueueDpc(), KeLowerIrql(), KiInsertTreeTimer(), KiLockDispatcherDatabase, KiRemoveTreeTimer, KiUnlockDispatcherDatabase(), KiWaitTest(), MAXIMUM_DPC_LIST_SIZE, MAXIMUM_PROCESSORS, NULL, _KDPC::Number, _KTIMER::Period, _DPC_ENTRY::Routine, _DISPATCHER_HEADER::SignalState, TIMER_EXPIRE_INCREMENT, and _DISPATCHER_HEADER::WaitListHead.

Referenced by KeSetSystemTime(), and KiTimerExpiration().

00340 : 00341 00342 This function is called to process a list of timers that have expired. 00343 00344 N.B. This function is called with the dispatcher database locked and 00345 returns with the dispatcher database unlocked. 00346 00347 Arguments: 00348 00349 ExpiredListHead - Supplies a pointer to a list of timers that have 00350 expired. 00351 00352 OldIrql - Supplies the previous IRQL. 00353 00354 Return Value: 00355 00356 None. 00357 00358 --*/ 00359 00360 { 00361 00362 LONG Count; 00363 PKDPC Dpc; 00364 DPC_ENTRY DpcList[MAXIMUM_DPC_LIST_SIZE]; 00365 LONG Index; 00366 LARGE_INTEGER Interval; 00367 KIRQL OldIrql1; 00368 LARGE_INTEGER SystemTime; 00369 PKTIMER Timer; 00370 00371 // 00372 // Capture the timer expiration time. 00373 // 00374 00375 KiQuerySystemTime(&SystemTime); 00376 00377 // 00378 // Remove the next timer from the expired timer list, set the state of 00379 // the timer to signaled, reinsert the timer in the timer tree if it is 00380 // periodic, and optionally call the DPC routine if one is specified. 00381 // 00382 00383 RestartScan: 00384 Count = 0; 00385 while (ExpiredListHead->Flink != ExpiredListHead) { 00386 Timer = CONTAINING_RECORD(ExpiredListHead->Flink, KTIMER, TimerListEntry); 00387 KiRemoveTreeTimer(Timer); 00388 Timer->Header.SignalState = 1; 00389 if (IsListEmpty(&Timer->Header.WaitListHead) == FALSE) { 00390 KiWaitTest(Timer, TIMER_EXPIRE_INCREMENT); 00391 } 00392 00393 // 00394 // If the timer is periodic, then compute the next interval time 00395 // and reinsert the timer in the timer tree. 00396 // 00397 // N.B. Even though the timer insertion is relative, it can still 00398 // fail if the period of the timer elapses in between computing 00399 // the time and inserting the timer in the table. If this happens, 00400 // try again. 00401 // 00402 if (Timer->Period != 0) { 00403 Interval.QuadPart = Int32x32To64(Timer->Period, - 10 * 1000); 00404 while (!KiInsertTreeTimer(Timer, Interval)) { 00405 ; 00406 } 00407 } 00408 00409 if (Timer->Dpc != NULL) { 00410 Dpc = Timer->Dpc; 00411 00412 // 00413 // If the DPC is explicitly targeted to another processor, then 00414 // queue the DPC to the target processor. Otherwise, capture the 00415 // DPC parameters for execution on the current processor. 00416 // 00417 00418 #if defined(NT_UP) 00419 00420 DpcList[Count].Dpc = Dpc; 00421 DpcList[Count].Routine = Dpc->DeferredRoutine; 00422 DpcList[Count].Context = Dpc->DeferredContext; 00423 Count += 1; 00424 if (Count == MAXIMUM_DPC_LIST_SIZE) { 00425 break; 00426 } 00427 00428 #else 00429 00430 if ((Dpc->Number >= MAXIMUM_PROCESSORS) && 00431 (((ULONG)Dpc->Number - MAXIMUM_PROCESSORS) != (ULONG)KeGetCurrentProcessorNumber())) { 00432 KeInsertQueueDpc(Dpc, 00433 ULongToPtr(SystemTime.LowPart), 00434 ULongToPtr(SystemTime.HighPart)); 00435 00436 } else { 00437 DpcList[Count].Dpc = Dpc; 00438 DpcList[Count].Routine = Dpc->DeferredRoutine; 00439 DpcList[Count].Context = Dpc->DeferredContext; 00440 Count += 1; 00441 if (Count == MAXIMUM_DPC_LIST_SIZE) { 00442 break; 00443 } 00444 } 00445 00446 #endif 00447 00448 } 00449 } 00450 00451 // 00452 // Unlock the dispacher database and process DPC list entries. 00453 // 00454 00455 if (Count != 0) { 00456 KiUnlockDispatcherDatabase(DISPATCH_LEVEL); 00457 Index = 0; 00458 do { 00459 00460 #if DBG && (defined(i386) || defined(ALPHA)) 00461 00462 // 00463 // Reset the dpc tick count. If the tick count handler, 00464 // which increments this value, detects that it has crossed 00465 // a certain threshold, a breakpoint will be generated. 00466 // 00467 00468 KeGetCurrentPrcb()->DebugDpcTime = 0; 00469 #endif 00470 00471 (DpcList[Index].Routine)(DpcList[Index].Dpc, 00472 DpcList[Index].Context, 00473 ULongToPtr(SystemTime.LowPart), 00474 ULongToPtr(SystemTime.HighPart)); 00475 00476 00477 Index += 1; 00478 } while (Index < Count); 00479 00480 // 00481 // If processing of the expired timer list was terminated because 00482 // the DPC List was full, then process any remaining entries. 00483 // 00484 00485 if (Count == MAXIMUM_DPC_LIST_SIZE) { 00486 KiLockDispatcherDatabase(&OldIrql1); 00487 goto RestartScan; 00488 } 00489 00490 KeLowerIrql(OldIrql); 00491 00492 } else { 00493 KiUnlockDispatcherDatabase(OldIrql); 00494 } 00495 00496 return; 00497 } }

LOGICAL FASTCALL KiTryToAcquireQueuedSpinLock IN PKSPIN_LOCK_QUEUE  QueuedLock  ) 
 

Referenced by KiInitializeKernel().

BOOLEAN KiTryToAcquireSpinLock IN PKSPIN_LOCK  SpinLock  ) 
 

Referenced by KdEnterDebugger(), KdLogDbgPrint(), KdPollBreakIn(), and KeFreezeExecution().

VOID KiUnexpectedInterrupt VOID   ) 
 

Referenced by KiInitializeKernel().

VOID KiUnlockDeviceQueue IN PKDEVICE_QUEUE  DeviceQueue,
IN KIRQL  OldIrql
 

VOID FASTCALL KiUnlockDispatcherDatabase IN KIRQL  OldIrql  ) 
 

Referenced by ExpCheckForWorker(), ExpFindCurrentThread(), 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(), KeTestAlertThread(), KeThawAllThreads(), KeUnstackDetachProcess(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), KiAttachProcess(), KiInSwapKernelStacks(), KiInSwapProcesses(), KiOutSwapKernelStacks(), KiOutSwapProcesses(), KiQuantumEnd(), KiScanReadyQueues(), KiTimerListExpire(), NtReplyWaitSendChannel(), NtSendWaitReplyChannel(), NtYieldExecution(), and PspReaper().

VOID FASTCALL KiUnwaitThread IN PRKTHREAD  Thread,
IN LONG_PTR  WaitStatus,
IN KPRIORITY  Increment
 

Definition at line 31 of file waitsup.c.

References _KPROCESS::BasePriority, _KQUEUE::CurrentCount, FALSE, _KTIMER::Header, Increment, _DISPATCHER_HEADER::Inserted, KiReadyThread(), KiRemoveTreeTimer, MEMORY_PRIORITY_FOREGROUND, _KWAIT_BLOCK::NextWaitBlock, NULL, PKQUEUE, PsPrioritySeperation, _KPROCESS::ThreadQuantum, TIME_CRITICAL_PRIORITY_BOUND, WAIT_QUANTUM_DECREMENT, and _KWAIT_BLOCK::WaitListEntry.

Referenced by KeAlertResumeThread(), KeAlertThread(), KeSetEvent(), KeSetEventBoostPriority(), KiActivateWaiterQueue(), KiInsertQueueApc(), and KiWaitTest().

00039 : 00040 00041 This function unwaits a thread, sets the thread's wait completion status, 00042 calculates the thread's new priority, and readies the thread for execution. 00043 00044 Arguments: 00045 00046 Thread - Supplies a pointer to a dispatcher object of type thread. 00047 00048 WaitStatus - Supplies the wait completion status. 00049 00050 Increment - Supplies the priority increment that is to be applied to 00051 the thread's priority. 00052 00053 Return Value: 00054 00055 None. 00056 00057 --*/ 00058 00059 { 00060 00061 KPRIORITY NewPriority; 00062 PKPROCESS Process; 00063 PKQUEUE Queue; 00064 PKTIMER Timer; 00065 PRKWAIT_BLOCK WaitBlock; 00066 00067 // 00068 // Set wait completion status, remove wait blocks from object wait 00069 // lists, and remove thread from wait list. 00070 // 00071 00072 Thread->WaitStatus |= WaitStatus; 00073 WaitBlock = Thread->WaitBlockList; 00074 do { 00075 RemoveEntryList(&WaitBlock->WaitListEntry); 00076 WaitBlock = WaitBlock->NextWaitBlock; 00077 } while (WaitBlock != Thread->WaitBlockList); 00078 00079 RemoveEntryList(&Thread->WaitListEntry); 00080 00081 // 00082 // If thread timer is still active, then cancel thread timer. 00083 // 00084 00085 Timer = &Thread->Timer; 00086 if (Timer->Header.Inserted != FALSE) { 00087 KiRemoveTreeTimer(Timer); 00088 } 00089 00090 // 00091 // If the thread is processing a queue entry, then increment the 00092 // count of currently active threads. 00093 // 00094 00095 Queue = Thread->Queue; 00096 if (Queue != NULL) { 00097 Queue->CurrentCount += 1; 00098 } 00099 00100 // 00101 // If the thread runs at a realtime priority level, then reset the 00102 // thread quantum. Otherwise, compute the next thread priority and 00103 // charge the thread for the wait operation. 00104 // 00105 00106 Process = Thread->ApcState.Process; 00107 if (Thread->Priority < LOW_REALTIME_PRIORITY) { 00108 if ((Thread->PriorityDecrement == 0) && 00109 (Thread->DisableBoost == FALSE)) { 00110 NewPriority = Thread->BasePriority + Increment; 00111 if (((PEPROCESS)Process)->Vm.MemoryPriority == MEMORY_PRIORITY_FOREGROUND) { 00112 NewPriority += PsPrioritySeperation; 00113 } 00114 00115 if (NewPriority > Thread->Priority) { 00116 if (NewPriority >= LOW_REALTIME_PRIORITY) { 00117 Thread->Priority = LOW_REALTIME_PRIORITY - 1; 00118 00119 } else { 00120 Thread->Priority = (SCHAR)NewPriority; 00121 } 00122 } 00123 } 00124 00125 if (Thread->BasePriority >= TIME_CRITICAL_PRIORITY_BOUND) { 00126 Thread->Quantum = Process->ThreadQuantum; 00127 00128 } else { 00129 Thread->Quantum -= WAIT_QUANTUM_DECREMENT; 00130 if (Thread->Quantum <= 0) { 00131 Thread->Quantum = Process->ThreadQuantum; 00132 Thread->Priority -= (Thread->PriorityDecrement + 1); 00133 if (Thread->Priority < Thread->BasePriority) { 00134 Thread->Priority = Thread->BasePriority; 00135 } 00136 00137 Thread->PriorityDecrement = 0; 00138 } 00139 } 00140 00141 } else { 00142 Thread->Quantum = Process->ThreadQuantum; 00143 } 00144 00145 // 00146 // Reready the thread for execution. 00147 // 00148 00149 KiReadyThread(Thread); 00150 return; 00151 }

VOID KiUserApcDispatcher IN PVOID  NormalContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2,
IN PKNORMAL_ROUTINE  NormalRoutine
 

VOID KiUserExceptionDispatcher IN PEXCEPTION_RECORD  ExceptionRecord,
IN PCONTEXT  ContextFrame
 

VOID FASTCALL KiWaitSatisfyAll IN PRKWAIT_BLOCK  WaitBlock  ) 
 

Definition at line 228 of file waitsup.c.

References KiWaitSatisfyAny, _KWAIT_BLOCK::NextWaitBlock, _KWAIT_BLOCK::Object, _KWAIT_BLOCK::Thread, and _KWAIT_BLOCK::WaitKey.

Referenced by KeWaitForMultipleObjects(), and KiWaitTest().

00234 : 00235 00236 This function satisfies a wait all and performs any side effects that 00237 are necessary. 00238 00239 Arguments: 00240 00241 WaitBlock - Supplies a pointer to a wait block. 00242 00243 Return Value: 00244 00245 None. 00246 00247 --*/ 00248 00249 { 00250 00251 PKMUTANT Object; 00252 PRKTHREAD Thread; 00253 PRKWAIT_BLOCK WaitBlock1; 00254 00255 // 00256 // If the wait type was WaitAny, then perform neccessary side effects on 00257 // the object specified by the wait block. Else perform necessary side 00258 // effects on all the objects that were involved in the wait operation. 00259 // 00260 00261 WaitBlock1 = WaitBlock; 00262 Thread = WaitBlock1->Thread; 00263 do { 00264 if (WaitBlock1->WaitKey != (CSHORT)STATUS_TIMEOUT) { 00265 Object = (PKMUTANT)WaitBlock1->Object; 00266 KiWaitSatisfyAny(Object, Thread); 00267 } 00268 00269 WaitBlock1 = WaitBlock1->NextWaitBlock; 00270 } while (WaitBlock1 != WaitBlock); 00271 00272 return; 00273 }

VOID FASTCALL KiWaitTest IN PVOID  Object,
IN KPRIORITY  Increment
 

Definition at line 277 of file waitsup.c.

References Event(), _KMUTANT::Header, Increment, KiUnwaitThread(), KiWaitSatisfyAll(), KiWaitSatisfyAny, MutantObject, _KWAIT_BLOCK::NextWaitBlock, NTSTATUS(), _KWAIT_BLOCK::Object, _KMUTANT::OwnerThread, _DISPATCHER_HEADER::SignalState, _KWAIT_BLOCK::Thread, _DISPATCHER_HEADER::Type, _KWAIT_BLOCK::WaitKey, and _KWAIT_BLOCK::WaitType.

Referenced by KeAlertResumeThread(), KeDetachProcess(), KeForceResumeThread(), KePulseEvent(), KeReleaseMutant(), KeReleaseSemaphore(), KeResumeThread(), KeRundownThread(), KeSetEvent(), KeSetProcess(), KeSetTimerEx(), KeTerminateThread(), KeThawAllThreads(), KeUnstackDetachProcess(), KiAttachProcess(), KiReadyThread(), and KiTimerListExpire().

00284 : 00285 00286 This function tests if a wait can be satisfied when an object attains 00287 a state of signaled. If a wait can be satisfied, then the subject thread 00288 is unwaited with a completion status that is the WaitKey of the wait 00289 block from the object wait list. As many waits as possible are satisfied. 00290 00291 Arguments: 00292 00293 Object - Supplies a pointer to a dispatcher object. 00294 00295 Return Value: 00296 00297 None. 00298 00299 --*/ 00300 00301 { 00302 00303 PKEVENT Event; 00304 PLIST_ENTRY ListHead; 00305 PRKWAIT_BLOCK NextBlock; 00306 PKMUTANT Mutant; 00307 PRKTHREAD Thread; 00308 PRKWAIT_BLOCK WaitBlock; 00309 PLIST_ENTRY WaitEntry; 00310 00311 // 00312 // As long as the signal state of the specified object is Signaled and 00313 // there are waiters in the object wait list, then try to satisfy a wait. 00314 // 00315 00316 Event = (PKEVENT)Object; 00317 ListHead = &Event->Header.WaitListHead; 00318 WaitEntry = ListHead->Flink; 00319 while ((Event->Header.SignalState > 0) && 00320 (WaitEntry != ListHead)) { 00321 WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry); 00322 Thread = WaitBlock->Thread; 00323 if (WaitBlock->WaitType != WaitAny) { 00324 00325 // 00326 // The wait type is wait all - if all the objects are in 00327 // a Signaled state, then satisfy the wait. 00328 // 00329 00330 NextBlock = WaitBlock->NextWaitBlock; 00331 while (NextBlock != WaitBlock) { 00332 if (NextBlock->WaitKey != (CSHORT)(STATUS_TIMEOUT)) { 00333 Mutant = (PKMUTANT)NextBlock->Object; 00334 if ((Mutant->Header.Type == MutantObject) && 00335 (Mutant->Header.SignalState <= 0) && 00336 (Thread == Mutant->OwnerThread)) { 00337 goto next; 00338 00339 } else if (Mutant->Header.SignalState <= 0) { 00340 goto scan; 00341 } 00342 } 00343 00344 next: 00345 NextBlock = NextBlock->NextWaitBlock; 00346 } 00347 00348 // 00349 // All objects associated with the wait are in the Signaled 00350 // state - satisfy the wait. 00351 // 00352 00353 WaitEntry = WaitEntry->Blink; 00354 KiWaitSatisfyAll(WaitBlock); 00355 00356 } else { 00357 00358 // 00359 // The wait type is wait any - satisfy the wait. 00360 // 00361 00362 WaitEntry = WaitEntry->Blink; 00363 KiWaitSatisfyAny((PKMUTANT)Event, Thread); 00364 } 00365 00366 KiUnwaitThread(Thread, (NTSTATUS)WaitBlock->WaitKey, Increment); 00367 00368 scan: 00369 WaitEntry = WaitEntry->Flink; 00370 } 00371 00372 return; 00373 } }


Variable Documentation

ULONG KiAdjustDpcThreshold
 

Definition at line 1112 of file ki.h.

UCHAR KiArgumentTable[]
 

Definition at line 1135 of file ki.h.

Referenced by KiInitSystem().

KSPIN_LOCK KiContextSwapLock
 

Definition at line 1113 of file ki.h.

Referenced by KiInitializeKernel().

PKDEBUG_ROUTINE KiDebugRoutine
 

Definition at line 1114 of file ki.h.

PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine
 

Definition at line 1115 of file ki.h.

KSPIN_LOCK KiDispatcherLock
 

Definition at line 1116 of file ki.h.

LIST_ENTRY KiDispatcherReadyListHead[MAXIMUM_PRIORITY]
 

Definition at line 1117 of file ki.h.

Referenced by KeSetAffinityThread(), KiFindReadyThread(), KiInitSystem(), KiReadyThread(), KiScanReadyQueues(), KiSetPriorityThread(), and NtYieldExecution().

ULONG KiDmaIoCoherency
 

Definition at line 1109 of file ki.h.

Referenced by KeFlushIoBuffers(), KeSetDmaIoCoherency(), and KiInitializeKernel().

ULONG KiEnableTimerWatchdog
 

Definition at line 1153 of file ki.h.

CCHAR KiFindFirstSetLeft[256]
 

Definition at line 1118 of file ki.h.

UCHAR KiFindLeftNibbleBitTable[]
 

Definition at line 1122 of file ki.h.

CALL_PERFORMANCE_DATA KiFlushSingleCallData
 

Definition at line 1119 of file ki.h.

Referenced by KeFlushSingleTb(), and KiInitSystem().

KSPIN_LOCK KiFreezeExecutionLock
 

Definition at line 1145 of file ki.h.

ULONG KiFreezeFlag
 

Definition at line 1234 of file ki.h.

Referenced by KdEnterDebugger(), KeFreezeExecution(), and KeThawExecution().

KSPIN_LOCK KiFreezeLockBackup
 

Definition at line 1233 of file ki.h.

ULONG_PTR KiHardwareTrigger
 

Definition at line 1120 of file ki.h.

KAFFINITY KiIdleSummary
 

Definition at line 1121 of file ki.h.

Referenced by KiInitializeKernel(), KiReadyThread(), and KiSelectNextThread().

ULONG KiMaximumDpcQueueDepth
 

Definition at line 1110 of file ki.h.

ULONG KiMinimumDpcRate
 

Definition at line 1111 of file ki.h.

LIST_ENTRY KiProcessInSwapListHead
 

Definition at line 1124 of file ki.h.

Referenced by KeSwapProcessOrStack(), KiAttachProcess(), KiInitSystem(), KiInSwapProcesses(), KiOutSwapProcesses(), and KiReadyThread().

LIST_ENTRY KiProcessOutSwapListHead
 

Definition at line 1125 of file ki.h.

Referenced by KeDetachProcess(), KeSwapProcessOrStack(), KeTerminateThread(), KeUnstackDetachProcess(), KiInitSystem(), KiOutSwapKernelStacks(), and KiOutSwapProcesses().

BOOLEAN KiProfileAlignmentFixup
 

Definition at line 1128 of file ki.h.

Referenced by KeStartProfile(), KeStopProfile(), and KiEmulateReference().

ULONG KiProfileAlignmentFixupCount
 

Definition at line 1130 of file ki.h.

Referenced by KiEmulateReference().

ULONG KiProfileAlignmentFixupInterval
 

Definition at line 1129 of file ki.h.

Referenced by KeQueryIntervalProfile(), KeSetIntervalProfile(), and KiEmulateReference().

ULONG KiProfileInterval
 

Definition at line 1131 of file ki.h.

Referenced by KeQueryIntervalProfile(), and KeSetIntervalProfile().

LIST_ENTRY KiProfileListHead
 

Definition at line 1132 of file ki.h.

Referenced by KeProfileInterruptWithSource(), KeStartProfile(), and KiInitSystem().

KSPIN_LOCK KiProfileLock
 

Definition at line 1133 of file ki.h.

LIST_ENTRY KiProfileSourceListHead
 

Definition at line 1127 of file ki.h.

Referenced by KeStartProfile(), KeStopProfile(), and KiInitSystem().

PRKTHREAD KiQuantumEnd(VOID)
 

Referenced by KiInitializeKernel().

ULONG KiReadySummary
 

Definition at line 1134 of file ki.h.

Referenced by KeSetAffinityThread(), KiFindReadyThread(), KiReadyThread(), KiScanReadyQueues(), KiSetPriorityThread(), and NtYieldExecution().

ULONG KiServiceLimit
 

Definition at line 1136 of file ki.h.

Referenced by KiInitSystem().

ULONG_PTR KiServiceTable[]
 

Definition at line 1137 of file ki.h.

Referenced by KiInitSystem().

CALL_PERFORMANCE_DATA KiSetEventCallData
 

Definition at line 1138 of file ki.h.

Referenced by KeSetEvent(), and KiInitSystem().

BOOLEAN KiSlavesStartExecution
 

Definition at line 1146 of file ki.h.

LIST_ENTRY KiStackInSwapListHead
 

Definition at line 1126 of file ki.h.

Referenced by KeSwapProcessOrStack(), KiInitSystem(), KiInSwapKernelStacks(), and KiReadyThread().

volatile ULONG KiSuspendState
 

Definition at line 1235 of file ki.h.

PSWAP_CONTEXT_NOTIFY_ROUTINE KiSwapContextNotifyRoutine
 

Definition at line 1147 of file ki.h.

Referenced by KeSetSwapContextNotifyRoutine().

KEVENT KiSwapEvent
 

Definition at line 1123 of file ki.h.

Referenced by KeBalanceSetManager(), KeDetachProcess(), KeSwapProcessOrStack(), KeTerminateThread(), KeUnstackDetachProcess(), KiAttachProcess(), KiInitSystem(), and KiReadyThread().

PTHREAD_SELECT_NOTIFY_ROUTINE KiThreadSelectNotifyRoutine
 

Definition at line 1148 of file ki.h.

Referenced by KeSetThreadSelectNotifyRoutine(), and KiFindReadyThread().

ULONG KiTickOffset
 

Definition at line 1139 of file ki.h.

Referenced by KeSetTimeIncrement(), KeUpdateSystemTime(), and KiCalibrateTimeAdjustment().

LARGE_INTEGER KiTimeIncrementReciprocal
 

Definition at line 1140 of file ki.h.

Referenced by KiInitializeKernel().

CCHAR KiTimeIncrementShiftCount
 

Definition at line 1141 of file ki.h.

Referenced by KiInitializeKernel().

KAFFINITY KiTimeProcessor
 

Definition at line 1143 of file ki.h.

KDPC KiTimerExpireDpc
 

Definition at line 1144 of file ki.h.

Referenced by KiCalibrateTimeAdjustment(), KiChkTimerExpireSysDpc(), and KiInitSystem().

LIST_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]
 

Definition at line 1142 of file ki.h.

Referenced by KeCheckForTimer(), KeSetSystemTime(), KiChkTimerExpireSysDpc(), KiInitSystem(), KiInsertTimerTable(), KiTimerExpiration(), and VerifierKeInitializeTimerEx().

PTIME_UPDATE_NOTIFY_ROUTINE KiTimeUpdateNotifyRoutine
 

Definition at line 1149 of file ki.h.

Referenced by KeSetTimeUpdateNotifyRoutine().

LIST_ENTRY KiWaitInListHead
 

Definition at line 1150 of file ki.h.

Referenced by KiInitSystem(), and KiOutSwapKernelStacks().

LIST_ENTRY KiWaitOutListHead
 

Definition at line 1151 of file ki.h.

Referenced by KiInitSystem(), and KiOutSwapKernelStacks().

CALL_PERFORMANCE_DATA KiWaitSingleCallData
 

Definition at line 1152 of file ki.h.

Referenced by KeWaitForSingleObject(), and KiInitSystem().


Generated on Sat May 15 19:44:29 2004 for test by doxygen 1.3.7