pwropt.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*++
  2. Copyright (c) 2015 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. pwropt.c
  5. Abstract:
  6. This module implements support for power management optimizations.
  7. Author:
  8. Evan Green 4-Sep-2015
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/kernel.h>
  16. #include "pmp.h"
  17. //
  18. // ---------------------------------------------------------------- Definitions
  19. //
  20. //
  21. // ------------------------------------------------------ Data Type Definitions
  22. //
  23. //
  24. // ----------------------------------------------- Internal Function Prototypes
  25. //
  26. //
  27. // -------------------------------------------------------------------- Globals
  28. //
  29. //
  30. // ------------------------------------------------------------------ Functions
  31. //
  32. PIDLE_HISTORY
  33. PmpCreateIdleHistory (
  34. ULONG Flags,
  35. ULONG Shift
  36. )
  37. /*++
  38. Routine Description:
  39. This routine creates an idle history structure, which tracks the idle
  40. history of a device or processor.
  41. Arguments:
  42. Flags - Supplies a bitfield of flags governing the creation and behavior of
  43. the idle history. See IDLE_HISTORY_* definitions.
  44. Shift - Supplies the logarithm of the number of history elements to store.
  45. That is, 1 << Shift will equal the number of history elements stored.
  46. Return Value:
  47. Returns a pointer to the new history on success.
  48. NULL on allocation failure.
  49. --*/
  50. {
  51. UINTN AllocationSize;
  52. PIDLE_HISTORY History;
  53. AllocationSize = sizeof(IDLE_HISTORY) + ((1 << Shift) * sizeof(ULONGLONG));
  54. if ((Flags & IDLE_HISTORY_NON_PAGED) != 0) {
  55. History = MmAllocateNonPagedPool(AllocationSize, PM_ALLOCATION_TAG);
  56. } else {
  57. History = MmAllocatePagedPool(AllocationSize, PM_ALLOCATION_TAG);
  58. }
  59. if (History == NULL) {
  60. return NULL;
  61. }
  62. RtlZeroMemory(History, AllocationSize);
  63. History->Flags = Flags;
  64. History->Shift = Shift;
  65. History->Data = (PULONGLONG)(History + 1);
  66. return History;
  67. }
  68. VOID
  69. PmpDestroyIdleHistory (
  70. PIDLE_HISTORY History
  71. )
  72. /*++
  73. Routine Description:
  74. This routine destroys an idle history structure.
  75. Arguments:
  76. History - Supplies a pointer to the idle history to destroy.
  77. Return Value:
  78. None.
  79. --*/
  80. {
  81. if ((History->Flags & IDLE_HISTORY_NON_PAGED) != 0) {
  82. MmFreeNonPagedPool(History);
  83. } else {
  84. MmFreePagedPool(History);
  85. }
  86. return;
  87. }
  88. VOID
  89. PmpIdleHistoryAddDataPoint (
  90. PIDLE_HISTORY History,
  91. ULONGLONG Value
  92. )
  93. /*++
  94. Routine Description:
  95. This routine adds a datapoint to the running idle history. This routine
  96. is not synchronized.
  97. Arguments:
  98. History - Supplies a pointer to the idle history.
  99. Value - Supplies the new data value to add.
  100. Return Value:
  101. None.
  102. --*/
  103. {
  104. ULONG NextIndex;
  105. NextIndex = History->NextIndex;
  106. History->Total -= History->Data[NextIndex];
  107. History->Total += Value;
  108. History->Data[NextIndex] = Value;
  109. NextIndex += 1;
  110. if (NextIndex == (1 << History->Shift)) {
  111. NextIndex = 0;
  112. }
  113. History->NextIndex = NextIndex;
  114. return;
  115. }
  116. ULONGLONG
  117. PmpIdleHistoryGetAverage (
  118. PIDLE_HISTORY History
  119. )
  120. /*++
  121. Routine Description:
  122. This routine returns the running average of the idle history.
  123. Arguments:
  124. History - Supplies a pointer to the idle history.
  125. Return Value:
  126. Returns the average idle duration.
  127. --*/
  128. {
  129. //
  130. // Return the (rounded) total divided by the number of elements.
  131. //
  132. return (History->Total + (1 << (History->Shift - 1))) >> History->Shift;
  133. }
  134. //
  135. // --------------------------------------------------------- Internal Functions
  136. //