Source code of Windows XP (NT5)
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.

130 lines
3.2 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. //#include <winbase.h>
  5. //
  6. //#include <nt.h>
  7. //#include <ntrtl.h>
  8. LARGE_INTEGER
  9. RtlEnlargedUnsignedMultiply (
  10. ULONG Multiplicand,
  11. ULONG Multiplier
  12. );
  13. ULONG
  14. RtlEnlargedUnsignedDivide (
  15. IN ULARGE_INTEGER Dividend,
  16. IN ULONG Divisor,
  17. IN PULONG Remainder
  18. );
  19. LARGE_INTEGER
  20. test (
  21. IN LARGE_INTEGER SetTime,
  22. IN LARGE_INTEGER PerfFreq
  23. );
  24. typedef struct _KUSER_SHARED_DATA {
  25. volatile ULONG TickCountLow;
  26. ULONG TickCountMultiplier;
  27. volatile ULONG ITimeLow;
  28. volatile ULONG ITime1High;
  29. volatile ULONG ITime2High;
  30. } KUSER_SHARED_DATA;
  31. #define MM_SHARED_USER_DATA_VA 0x7FFE0000
  32. #define SharedUserData ((KUSER_SHARED_DATA * const) MM_SHARED_USER_DATA_VA)
  33. __cdecl
  34. main ()
  35. {
  36. LARGE_INTEGER SetTime, PerfFreq, PerfCount, SystemTime;
  37. FILETIME FileTime;
  38. LARGE_INTEGER li;
  39. QueryPerformanceFrequency(&PerfFreq);
  40. QueryPerformanceCounter(&PerfCount);
  41. do {
  42. SystemTime.HighPart = SharedUserData->ITime1High;
  43. SystemTime.LowPart = SharedUserData->ITimeLow;
  44. } while (SystemTime.HighPart != SharedUserData->ITime2High);
  45. //GetSystemTimeAsFileTime(&FileTime);
  46. //SystemTime.HighPart = FileTime.dwHighDateTime;
  47. //SystemTime.LowPart = FileTime.dwLowDateTime;
  48. li = test (SystemTime, PerfFreq);
  49. printf ("Perf freq.: %08lx:%08lx\n", PerfFreq.HighPart, PerfFreq.LowPart);
  50. printf ("Int time..: %08lx:%08lx\n", SystemTime.HighPart, SystemTime.LowPart);
  51. printf ("Perf count: %08lx:%08lx\n", PerfCount.HighPart, PerfCount.LowPart);
  52. printf ("New perf..: %08lx:%08lx\n", li.HighPart, li.LowPart);
  53. li.QuadPart = li.QuadPart - PerfCount.QuadPart;
  54. printf ("Diff......: %08lx:%08lx\n", li.HighPart, li.LowPart);
  55. }
  56. LARGE_INTEGER
  57. test (
  58. IN LARGE_INTEGER SetTime,
  59. IN LARGE_INTEGER PerfFreq
  60. )
  61. {
  62. LARGE_INTEGER PerfCount;
  63. ULARGE_INTEGER li;
  64. LARGE_INTEGER NewPerf;
  65. ULONG cl, divisor;
  66. //
  67. // Compute performance counter for current InterruptTime
  68. //
  69. // Multiply SetTime * PerfCount and obtain 96bit result
  70. // in cl, li.LowPart, li.HighPart
  71. li.QuadPart = RtlEnlargedUnsignedMultiply (
  72. (ULONG) SetTime.LowPart,
  73. (ULONG) PerfFreq.LowPart
  74. ).QuadPart;
  75. cl = li.LowPart;
  76. li.QuadPart = li.HighPart +
  77. RtlEnlargedUnsignedMultiply (
  78. (ULONG) SetTime.LowPart,
  79. (ULONG) PerfFreq.HighPart
  80. ).QuadPart;
  81. li.QuadPart = li.QuadPart +
  82. RtlEnlargedUnsignedMultiply (
  83. (ULONG) SetTime.HighPart,
  84. (ULONG) PerfFreq.LowPart
  85. ).QuadPart;
  86. li.HighPart = li.HighPart + SetTime.HighPart * PerfFreq.HighPart;
  87. printf ("Time*PerfFreq = %08x:%08x:%08x\n",
  88. li.HighPart,
  89. li.LowPart,
  90. cl
  91. );
  92. // Divide 96bit result by 10,000,000
  93. divisor = 10000000;
  94. NewPerf.HighPart = RtlEnlargedUnsignedDivide(li, divisor, &li.HighPart);
  95. li.LowPart = cl;
  96. NewPerf.LowPart = RtlEnlargedUnsignedDivide(li, divisor, NULL);
  97. return NewPerf;
  98. }