/*++ Copyright (c) 1989 Microsoft Corporation Module Name: kernldat.c Abstract: This module contains the declaration and allocation of kernel data structures. Author: David N. Cutler (davec) 12-Mar-1989 Revision History: --*/ #include "ki.h" // // The following data is read/write data that is grouped together for // performance. The layout of this data is important and must not be // changed. // // KiDispatcherReadyListHead - This is an array of type list entry. The // elements of the array are indexed by priority. Each element is a list // head for a set of threads that are in a ready state for the respective // priority. This array is used by the find next thread code to speed up // search for a ready thread when a thread becomes unrunnable. See also // KiReadySummary. // LIST_ENTRY KiDispatcherReadyListHead[MAXIMUM_PRIORITY]; // // KiIdleSummary - This is the set of processors that are idle. It is used by // the ready thread code to speed up the search for a thread to preempt // when a thread becomes runnable. // KAFFINITY KiIdleSummary = 0; // // KiReadySummary - This is the set of dispatcher ready queues that are not // empty. A member is set in this set for each priority that has one or // more entries in its respective dispatcher ready queues. // ULONG KiReadySummary = 0; // // KiTimerTableListHead - This is a array of list heads that anchor the // individual timer lists. // LIST_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE]; // // KiSwapContextNotifyRoutine - This is the address of a callout routine // which is called at each context switch if the address is not NULL. // PSWAP_CONTEXT_NOTIFY_ROUTINE KiSwapContextNotifyRoutine; // // KiThreadSelectNotifyRoutine - This is the address of a callout routine // which is called when a thread is being selected for execution if // the address is not NULL. // PTHREAD_SELECT_NOTIFY_ROUTINE KiThreadSelectNotifyRoutine; // // KiTimeUpdateNotifyRoutine - This is the address of a callout routine // which is called when the runtime for a thread is updated if the // address is not NULL. // PTIME_UPDATE_NOTIFY_ROUTINE KiTimeUpdateNotifyRoutine; // // Public kernel data declaration and allocation. // // KeActiveProcessors - This is the set of processors that active in the // system. // KAFFINITY KeActiveProcessors = 0; // // KeBootTime - This is the absolute time when the system was booted. // LARGE_INTEGER KeBootTime; // // KeBugCheckCallbackListHead - This is the list head for registered // bug check callback routines. // LIST_ENTRY KeBugCheckCallbackListHead; // // KeBugCheckCallbackLock - This is the spin lock that guards the bug // check callback list. // KSPIN_LOCK KeBugCheckCallbackLock; // // KeDcacheFlushCount - This is the number of data cache flushes that have // been performed since the system was booted. // ULONG KeDcacheFlushCount = 0; // // KeIcacheFlushCount - This is the number of instruction cache flushes that // have been performed since the system was booted. // ULONG KeIcacheFlushCount = 0; // // KeGdiFlushUserBatch - This is the address of the GDI user batch flush // routine which is initialized when the win32k subsystem is loaded. // PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch; // // KeLoaderBlock - This is a pointer to the loader parameter block which is // constructed by the OS Loader. // PLOADER_PARAMETER_BLOCK KeLoaderBlock = NULL; // // KeMinimumIncrement - This is the minimum time between clock interrupts // in 100ns units that is supported by the host HAL. // ULONG KeMinimumIncrement; // // KeNumberProcessors - This is the number of processors in the configuration. // If is used by the ready thread and spin lock code to determine if a // faster algorithm can be used for the case of a single processor system. // The value of this variable is set when processors are initialized. // CCHAR KeNumberProcessors = 0; // // KeNumberProcessIds - This is a MIPS specific value and defines the number // of process id tags in the host TB. // #if defined(_MIPS_) ULONG KeNumberProcessIds; #endif // // KeNumberTbEntries - This is a MIPS specific value and defines the number // of TB entries in the host TB. // #if defined(_MIPS_) ULONG KeNumberTbEntries; #endif // // KeRegisteredProcessors - This is the maxumum number of processors // which should utilized by the system. // #if !defined(NT_UP) #if DBG ULONG KeRegisteredProcessors = 4; ULONG KeLicensedProcessors; #else ULONG KeRegisteredProcessors = 2; ULONG KeLicensedProcessors; #endif #endif // // KeProcessorArchitecture - Architecture of all processors present in system. // See PROCESSOR_ARCHITECTURE_ defines in ntexapi.h // USHORT KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN; // // KeProcessorLevel - Architectural specific processor level of all processors // present in system. USHORT KeProcessorLevel = 0; // // KeProcessorRevision - Architectural specific processor revision number that is // the least common denominator of all processors present in system. // USHORT KeProcessorRevision = 0; // // KeFeatureBits - Architectural specific processor features present // on all processors. // ULONG KeFeatureBits = 0; // // KeServiceDescriptorTable - This is a table of descriptors for system // service providers. Each entry in the table describes the base // address of the dispatch table and the number of services provided. // KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[NUMBER_SERVICE_TABLES]; KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[NUMBER_SERVICE_TABLES]; // // KeThreadSwitchCounters - These counters record the number of times a // thread can be scheduled on the current processor, any processor, // or the last processor it ran on. // KTHREAD_SWITCH_COUNTERS KeThreadSwitchCounters; // // KeTimeIncrement - This is the nominal number of 100ns units that are to // be added to the system time at each interval timer interupt. This // value is set by the HAL and is used to compute the dure time for // timer table entries. // ULONG KeTimeIncrement; // // KeTimeSynchronization - This variable controls whether time synchronization // is performed using the realtime clock (TRUE) or whether it is under the // control of a service (FALSE). // BOOLEAN KeTimeSynchronization = TRUE; // // KeUserApcDispatcher - This is the address of the user mode APC dispatch // code. This address is looked up in NTDLL.DLL during initialization // of the system. // ULONG KeUserApcDispatcher; // // KeUserCallbackDispatcher - This is the address of the user mode callback // dispatch code. This address is looked up in NTDLL.DLL during // initialization of the system. // ULONG KeUserCallbackDispatcher; // // KeUserExceptionDispatcher - This is the address of the user mode exception // dispatch code. This address is looked up in NTDLL.DLL during system // initialization. // ULONG KeUserExceptionDispatcher; // // KeRaiseUserExceptionDispatcher - This is the address of the raise user // mode exception dispatch code. This address is looked up in NTDLL.DLL // during system initialization. // ULONG KeRaiseUserExceptionDispatcher; // // Private kernel data declaration and allocation. // // KiBugCodeMessages - Address of where the BugCode messages can be found. // #if DEVL PMESSAGE_RESOURCE_DATA KiBugCodeMessages = NULL; #endif // // KiDmaIoCoherency - This determines whether the host platform supports // coherent DMA I/O. // ULONG KiDmaIoCoherency; // // KiMaximumSearchCount - this is the maximum number of timers entries that // have had to be examined to insert in the timer tree. // ULONG KiMaximumSearchCount = 0; // // KiDebugRoutine - This is the address of the kernel debugger. Initially // this is filled with the address of a routine that just returns. If // the system debugger is present in the system, then it sets this // location to the address of the systemn debugger's routine. // PKDEBUG_ROUTINE KiDebugRoutine; // // KiDebugSwitchRoutine - This is the address of the kernel debuggers // processor switch routine. This is used on an MP system to // switch host processors while debugging. // PKDEBUG_SWITCH_ROUTINE KiDebugSwitchRoutine; // // KiDispatcherLock - This is the spin lock that guards the dispatcher // database. // extern KSPIN_LOCK KiDispatcherLock; CCHAR KiFindFirstSetRight[256] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; CCHAR KiFindFirstSetLeft[256] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; // // KiFreezeExecutionLock - This is the spin lock that guards the freezing // of execution. // extern KSPIN_LOCK KiFreezeExecutionLock; // // KiFreezeLockBackup - For debug builds only. Allows kernel debugger to // be entered even FreezeExecutionLock is jammed. // extern KSPIN_LOCK KiFreezeLockBackup; // // KiFreezeFlag - For debug builds only. Flags to track and signal non- // normal freezelock conditions. // ULONG KiFreezeFlag; // // KiSuspenState - Flag to track suspend/resume state of processors // volatile ULONG KiSuspendState; // // KiFindLeftNibbleBitTable - This a table that is used to find the left most bit in // a 4-bit nibble. // UCHAR KiFindLeftNibbleBitTable[] = {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3}; // // KiProcessorBlock - This is an array of pointers to processor control blocks. // The elements of the array are indexed by processor number. Each element // is a pointer to the processor control block for one of the processors // in the configuration. This array is used by various sections of code // that need to effect the execution of another processor. // PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS]; // // KiSwapEvent - This is the event that is used to wake up the balance set // thread to inswap processes, outswap processes, and to inswap kernel // stacks. // KEVENT KiSwapEvent; // // KiProcessInSwapListHead - This is the list of processes that are waiting // to be inswapped. // LIST_ENTRY KiProcessInSwapListHead; // // KiProcessOutSwapListHead - This is the list of processes that are waiting // to be outswapped. // LIST_ENTRY KiProcessOutSwapListHead; // // KiStackInSwapListHead - This is the list of threads that are waiting // to get their stack inswapped before they can run. Threads are // inserted in this list in ready thread and removed by the balance // set thread. // LIST_ENTRY KiStackInSwapListHead; // // KiProfileSourceListHead - The list of profile sources that are currently // active. // LIST_ENTRY KiProfileSourceListHead; // // KiProfileAlignmentFixup - Indicates whether alignment fixup profiling // is active. // BOOLEAN KiProfileAlignmentFixup; // // KiProfileAlignmentFixupInterval - Indicates the current alignment fixup // profiling interval. // ULONG KiProfileAlignmentFixupInterval; // // KiProfileAlignmentFixupCount - Indicates the current alignment fixup // count. // ULONG KiProfileAlignmentFixupCount; // // KiProfileInterval - The profile interval in 100ns units. // ULONG KiProfileInterval = DEFAULT_PROFILE_INTERVAL; // // KiProfileListHead - This is the list head for the profile list. // LIST_ENTRY KiProfileListHead; // // KiProfileLock - This is the spin lock that guards the profile list. // extern KSPIN_LOCK KiProfileLock; // // KiTimerExpireDpc - This is the Deferred Procedure Call (DPC) object that // is used to process the timer queue when a timer has expired. // KDPC KiTimerExpireDpc; // // KiTimeIncrementReciprocal - This is the reciprocal fraction of the time // increment value that is specified by the HAL when the system is // booted. // LARGE_INTEGER KiTimeIncrementReciprocal; // // KiTimeIncrementShiftCount - This is the shift count that corresponds to // the time increment reciprocal value. // CCHAR KiTimeIncrementShiftCount; // // KiWaitInListHead - This is a list of threads that are waiting with a // resident kernel stack. // LIST_ENTRY KiWaitInListHead; // // KiWaitOutListHead - This is a list of threads that are either waiting // with a kernel stack that is nonresident or are not elligible to // have their stack swapped. // LIST_ENTRY KiWaitOutListHead; // // Private kernel data declaration and allocation. // // // KiIpiCounts - Instrumentation counters for IPI requests. // Each processor has it's own set. Intstrumentation build only. // #if NT_INST KIPI_COUNTS KiIpiCounts[MAXIMUM_PROCESSORS]; #endif // NT_INST // // KiMasterPid - This is the master PID that is used to assign PID's to // processes. // #if defined(_PPC_) ULONG KiMasterPid; // // KiMasterSequence - This is the master sequence number that is used to // assign PID's to processes. // ULONG KiMasterSequence = 1; // // KiProcessIdWrapLock - This is the spin lock that is used to provide // mutual exclusion between the TB flush routines and the process // swap code when PID roll over occurs. // KSPIN_LOCK KiProcessIdWrapLock = 0; #endif // // KxUnexpectedInterrupt - This is the interrupt object that is used to // populate the interrupt vector table for interrupt that are not // connected to any interrupt. // #if defined(_MIPS_) || defined(_ALPHA_) || defined(_PPC_) KINTERRUPT KxUnexpectedInterrupt; #endif // // Performance data declaration and allocation. // // KiFlushSingleCallData - This is the call performance data for the kernel // flush single TB function. // #if defined(_COLLECT_FLUSH_SINGLE_CALLDATA_) CALL_PERFORMANCE_DATA KiFlushSingleCallData; #endif // // KiSetEventCallData - This is the call performance data for the kernel // set event function. // #if defined(_COLLECT_SET_EVENT_CALLDATA_) CALL_PERFORMANCE_DATA KiSetEventCallData; #endif // // KiWaitSingleCallData - This is the call performance data for the kernel // wait for single object function. // #if defined(_COLLECT_WAIT_SINGLE_CALLDATA_) CALL_PERFORMANCE_DATA KiWaitSingleCallData; #endif