Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
3.4 KiB

  1. /*++
  2. Copyright (c) 1995 Intel Corporation
  3. Module Name:
  4. i64perfc.c copied from simperfc.c
  5. Abstract:
  6. This module implements the routines to support performance counters.
  7. Author:
  8. 14-Apr-1995
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "halp.h"
  14. #include "eisa.h"
  15. //
  16. // Define and initialize the 64-bit count of total system cycles used
  17. // as the performance counter.
  18. //
  19. ULONGLONG HalpCycleCount = 0;
  20. BOOLEAN HalpITCCalibrate = TRUE; // XXTF
  21. extern ULONGLONG HalpITCFrequency;
  22. extern ULONGLONG HalpClockCount;
  23. #if 0
  24. VOID
  25. HalpCheckPerformanceCounter(
  26. VOID
  27. )
  28. Routine Description:
  29. This function is called every system clock interrupt in order to
  30. check for wrap of the performance counter. The function must handle
  31. a wrap if it is detected.
  32. N.B. - This function was from the Alpha HAL.
  33. This function must be called at CLOCK_LEVEL.
  34. Arguments:
  35. None.
  36. Return Value:
  37. None.
  38. {
  39. return;
  40. } // HalpCheckPerformanceCounter()
  41. #endif // 0
  42. LARGE_INTEGER
  43. KeQueryPerformanceCounter (
  44. OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  45. )
  46. /*++
  47. Routine Description:
  48. This routine returns current 64-bit performance counter and,
  49. optionally, the Performance Frequency.
  50. Arguments:
  51. PerformanceFrequency - optionally, supplies the address
  52. of a variable to receive the performance counter frequency.
  53. Return Value:
  54. Current value of the performance counter will be returned.
  55. --*/
  56. {
  57. LARGE_INTEGER result;
  58. if (ARGUMENT_PRESENT(PerformanceFrequency)) {
  59. PerformanceFrequency->QuadPart = HalpITCFrequency;
  60. }
  61. result.QuadPart = HalpReadITC();
  62. return result;
  63. } // KeQueryPerformanceCounter()
  64. VOID
  65. HalCalibratePerformanceCounter (
  66. IN LONG volatile *Number,
  67. IN ULONGLONG NewCount
  68. )
  69. /*++
  70. Routine Description:
  71. This routine sets the performance counter value for the current
  72. processor to the specified valueo.
  73. The reset is done such that the resulting value is closely
  74. synchronized with other processors in the configuration.
  75. Arguments:
  76. Number - Supplies a pointer to count of the number of processors in
  77. the configuration.
  78. Return Value:
  79. None.
  80. --*/
  81. {
  82. KSPIN_LOCK Lock;
  83. KIRQL OldIrql;
  84. if ( HalpITCCalibrate ) {
  85. //
  86. // Raise IRQL to HIGH_LEVEL, decrement the number of processors, and
  87. // wait until the number is zero.
  88. //
  89. KeInitializeSpinLock(&Lock);
  90. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  91. PCR->HalReserved[CURRENT_ITM_VALUE_INDEX] = NewCount + HalpClockCount;
  92. HalpWriteITM( PCR->HalReserved[CURRENT_ITM_VALUE_INDEX] );
  93. if (ExInterlockedDecrementLong((PLONG)Number, &Lock) != RESULT_ZERO) {
  94. do {
  95. } while (*((LONG volatile *)Number) !=0);
  96. }
  97. //
  98. // Write the compare register with defined current ITM value,
  99. // and set the performance counter for the current processor
  100. // with the passed count.
  101. //
  102. HalpWriteITC( NewCount );
  103. //
  104. // Restore IRQL to its previous value and return.
  105. //
  106. KeLowerIrql(OldIrql);
  107. } else {
  108. *Number = 0;
  109. }
  110. return;
  111. } // HalCalibratePerformanceCounter()