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

miscc.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KeEnterCriticalRegion (VOID)
VOID KeLeaveCriticalRegion (VOID)
ULONGLONG KeQueryInterruptTime (VOID)
VOID KeQuerySystemTime (OUT PLARGE_INTEGER CurrentTime)
VOID KeQueryTickCount (OUT PLARGE_INTEGER CurrentCount)
ULONG KeQueryTimeIncrement (VOID)
VOID KeSetDmaIoCoherency (IN ULONG Attributes)
VOID KeSetSystemTime (IN PLARGE_INTEGER NewTime, OUT PLARGE_INTEGER OldTime, IN BOOLEAN AdjustInterruptTime, IN PLARGE_INTEGER HalTimeToSet OPTIONAL)
BOOLEAN KiAdjustInterruptTime (IN LONGLONG TimeDelta)
VOID KiCalibrateTimeAdjustment (PADJUST_INTERRUPT_TIME_CONTEXT Adjust)
VOID KeSetTimeIncrement (IN ULONG MaximumIncrement, IN ULONG MinimumIncrement)
BOOLEAN KeAddSystemServiceTable (IN PULONG_PTR Base, IN PULONG Count OPTIONAL, IN ULONG Limit, IN PUCHAR Number, IN ULONG Index)
VOID FASTCALL KeSetSwapContextNotifyRoutine (IN PSWAP_CONTEXT_NOTIFY_ROUTINE NotifyRoutine)
VOID FASTCALL KeSetThreadSelectNotifyRoutine (IN PTHREAD_SELECT_NOTIFY_ROUTINE NotifyRoutine)
VOID FASTCALL KeSetTimeUpdateNotifyRoutine (IN PTIME_UPDATE_NOTIFY_ROUTINE NotifyRoutine)
KAFFINITY KeQueryActiveProcessors (VOID)


Function Documentation

BOOLEAN KeAddSystemServiceTable IN PULONG_PTR  Base,
IN PULONG Count  OPTIONAL,
IN ULONG  Limit,
IN PUCHAR  Number,
IN ULONG  Index
 

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

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

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

VOID KeEnterCriticalRegion VOID   ) 
 

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

References KeGetCurrentThread.

00047 : 00048 00049 This function disables kernel APC's. 00050 00051 N.B. The following code does not require any interlocks. There are 00052 two cases of interest: 1) On an MP system, the thread cannot 00053 be running on two processors as once, and 2) if the thread is 00054 is interrupted to deliver a kernel mode APC which also calls 00055 this routine, the values read and stored will stack and unstack 00056 properly. 00057 00058 Arguments: 00059 00060 None. 00061 00062 Return Value: 00063 00064 None. 00065 00066 --*/ 00067 00068 { 00069 // 00070 // Simply directly disable kernel APCs. 00071 // 00072 00073 KeGetCurrentThread()->KernelApcDisable -= 1; 00074 return; 00075 }

VOID KeLeaveCriticalRegion VOID   ) 
 

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

References KiLeaveCriticalRegion.

00086 : 00087 00088 This function enables kernel APC's and requests an APC interrupt if 00089 appropriate. 00090 00091 Arguments: 00092 00093 None. 00094 00095 Return Value: 00096 00097 None. 00098 00099 --*/ 00100 00101 { 00102 00103 // 00104 // Increment the kernel APC disable count. If the resultant count is 00105 // zero and the thread's kernel APC List is not empty, then request an 00106 // APC interrupt. 00107 // 00108 // For multiprocessor performance, the following code utilizes the fact 00109 // that queuing an APC is done by first queuing the APC, then checking 00110 // the AST disable count. The following code increments the disable 00111 // count first, checks to determine if it is zero, and then checks the 00112 // kernel AST queue. 00113 // 00114 // See also KiInsertQueueApc(). 00115 // 00116 00117 KiLeaveCriticalRegion(); 00118 return; 00119 }

KAFFINITY KeQueryActiveProcessors VOID   ) 
 

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

References KeActiveProcessors, and PAGED_CODE.

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

ULONGLONG KeQueryInterruptTime VOID   ) 
 

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

Referenced by ExGetNextWakeTime(), and KiCalibrateTimeAdjustment().

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

VOID KeQuerySystemTime OUT PLARGE_INTEGER  CurrentTime  ) 
 

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

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

00159 : 00160 00161 This function returns the current system time by determining when the 00162 time is stable and then returning its value. 00163 00164 Arguments: 00165 00166 CurrentTime - Supplies a pointer to a variable that will receive the 00167 current system time. 00168 00169 Return Value: 00170 00171 None. 00172 00173 --*/ 00174 00175 { 00176 00177 KiQuerySystemTime(CurrentTime); 00178 return; 00179 }

VOID KeQueryTickCount OUT PLARGE_INTEGER  CurrentCount  ) 
 

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

Referenced by CcFlushCache(), IoAcquireRemoveLockEx(), IopFindLegacyDeviceNode(), IopInitializeDeviceInstanceKey(), IoReleaseRemoveLockEx(), IoReportDetectedDevice(), MiAllocateSpecialPool(), MiInsertWsle(), MmFreeSpecialPool(), RtlAcquireRemoveLockEx(), RtlReleaseRemoveLock(), ViInjectResourceFailure(), and ViTrimAllSystemPagableMemory().

00188 : 00189 00190 This function returns the current tick count by determining when the 00191 count is stable and then returning its value. 00192 00193 Arguments: 00194 00195 CurrentCount - Supplies a pointer to a variable that will receive the 00196 current tick count. 00197 00198 Return Value: 00199 00200 None. 00201 00202 --*/ 00203 00204 { 00205 00206 KiQueryTickCount(CurrentCount); 00207 return; 00208 }

ULONG KeQueryTimeIncrement VOID   ) 
 

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

References KeMaximumIncrement.

Referenced by CcInitializeCacheManager().

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

VOID KeSetDmaIoCoherency IN ULONG  Attributes  ) 
 

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

References KiDmaIoCoherency.

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

VOID FASTCALL KeSetSwapContextNotifyRoutine IN PSWAP_CONTEXT_NOTIFY_ROUTINE  NotifyRoutine  ) 
 

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

References KiSwapContextNotifyRoutine, and PAGED_CODE.

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

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

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

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

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

VOID FASTCALL KeSetThreadSelectNotifyRoutine IN PTHREAD_SELECT_NOTIFY_ROUTINE  NotifyRoutine  ) 
 

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

References KiThreadSelectNotifyRoutine, and PAGED_CODE.

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

VOID KeSetTimeIncrement IN ULONG  MaximumIncrement,
IN ULONG  MinimumIncrement
 

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

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

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

VOID FASTCALL KeSetTimeUpdateNotifyRoutine IN PTIME_UPDATE_NOTIFY_ROUTINE  NotifyRoutine  ) 
 

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

References KiTimeUpdateNotifyRoutine, and PAGED_CODE.

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

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 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 }


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