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.

307 lines
6.5 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. numa.c
  5. Abstract:
  6. This module implements Win32 Non Uniform Memory Architecture
  7. information APIs.
  8. Author:
  9. Peter Johnston (peterj) 21-Sep-2000
  10. Revision History:
  11. --*/
  12. #include "basedll.h"
  13. BOOL
  14. WINAPI
  15. GetNumaHighestNodeNumber(
  16. PULONG HighestNodeNumber
  17. )
  18. /*++
  19. Routine Description:
  20. Return the (current) highest numbered node in the system.
  21. Arguments:
  22. HighestNodeNumber Supplies a pointer to receive the number of
  23. last (highest) node in the system.
  24. Return Value:
  25. TRUE unless something impossible happened.
  26. --*/
  27. {
  28. NTSTATUS Status;
  29. ULONG ReturnedSize;
  30. ULONGLONG Information;
  31. PSYSTEM_NUMA_INFORMATION Numa;
  32. Numa = (PSYSTEM_NUMA_INFORMATION)&Information;
  33. Status = NtQuerySystemInformation(SystemNumaProcessorMap,
  34. Numa,
  35. sizeof(Information),
  36. &ReturnedSize);
  37. if (!NT_SUCCESS(Status)) {
  38. //
  39. // This can't possibly happen. Attempt to handle it
  40. // gracefully.
  41. //
  42. BaseSetLastNTError(Status);
  43. return FALSE;
  44. }
  45. if (ReturnedSize < sizeof(ULONG)) {
  46. //
  47. // Nor can this.
  48. //
  49. SetLastError(ERROR_INVALID_PARAMETER);
  50. return FALSE;
  51. }
  52. //
  53. // Return the number of nodes in the system.
  54. //
  55. *HighestNodeNumber = Numa->HighestNodeNumber;
  56. return TRUE;
  57. }
  58. BOOL
  59. WINAPI
  60. GetNumaProcessorNode(
  61. UCHAR Processor,
  62. PUCHAR NodeNumber
  63. )
  64. /*++
  65. Routine Description:
  66. Return the Node number for a given processor.
  67. Arguments:
  68. Processor Supplies the processor number.
  69. NodeNumber Supplies a pointer to the UCHAR to receive the
  70. node number this processor belongs to.
  71. Return Value:
  72. BOOL - TRUE if function succeeded, FALSE if it failed. If it
  73. failed because the processor wasn't present, then set the
  74. NodeNumber to 0xFF
  75. --*/
  76. {
  77. ULONGLONG Mask;
  78. NTSTATUS Status;
  79. ULONG ReturnedSize;
  80. UCHAR Node;
  81. SYSTEM_NUMA_INFORMATION Map;
  82. //
  83. // If the requested processor number is not reasonable, return
  84. // error value.
  85. //
  86. if (Processor >= MAXIMUM_PROCESSORS) {
  87. *NodeNumber = 0xFF;
  88. SetLastError(ERROR_INVALID_PARAMETER);
  89. return FALSE;
  90. }
  91. //
  92. // Get the Node -> Processor Affinity map from the system.
  93. //
  94. Status = NtQuerySystemInformation(SystemNumaProcessorMap,
  95. &Map,
  96. sizeof(Map),
  97. &ReturnedSize);
  98. if (!NT_SUCCESS(Status)) {
  99. //
  100. // This can't happen,... but try to stay sane if possible.
  101. //
  102. *NodeNumber = 0xFF;
  103. BaseSetLastNTError(Status);
  104. return FALSE;
  105. }
  106. //
  107. // Look thru the nodes returned for the node in which the
  108. // requested processor's affinity is non-zero.
  109. //
  110. Mask = 1 << Processor;
  111. for (Node = 0; Node <= Map.HighestNodeNumber; Node++) {
  112. if ((Map.ActiveProcessorsAffinityMask[Node] & Mask) != 0) {
  113. *NodeNumber = Node;
  114. return TRUE;
  115. }
  116. }
  117. //
  118. // Didn't find this processor in any node, return error value.
  119. //
  120. *NodeNumber = 0xFF;
  121. SetLastError(ERROR_INVALID_PARAMETER);
  122. return FALSE;
  123. }
  124. BOOL
  125. WINAPI
  126. GetNumaNodeProcessorMask(
  127. UCHAR Node,
  128. PULONGLONG ProcessorMask
  129. )
  130. /*++
  131. Routine Description:
  132. This routine is used to obtain the bitmask of processors for a
  133. given node.
  134. Arguments:
  135. Node Supplies the Node number for which the set of
  136. processors is returned.
  137. ProcessorMask Pointer to a ULONGLONG to receivethe bitmask of
  138. processors on this node.
  139. Return Value:
  140. TRUE is the Node number was reasonable, FALSE otherwise.
  141. --*/
  142. {
  143. NTSTATUS Status;
  144. ULONG ReturnedSize;
  145. SYSTEM_NUMA_INFORMATION Map;
  146. //
  147. // Get the node -> processor mask table from the system.
  148. //
  149. Status = NtQuerySystemInformation(SystemNumaProcessorMap,
  150. &Map,
  151. sizeof(Map),
  152. &ReturnedSize);
  153. if (!NT_SUCCESS(Status)) {
  154. //
  155. // This can't possibly have happened.
  156. //
  157. BaseSetLastNTError(Status);
  158. return FALSE;
  159. }
  160. //
  161. // If the requested node doesn't exist, return a zero processor
  162. // mask.
  163. //
  164. if (Node > Map.HighestNodeNumber) {
  165. SetLastError(ERROR_INVALID_PARAMETER);
  166. return FALSE;
  167. }
  168. //
  169. // Return the processor mask for the requested node.
  170. //
  171. *ProcessorMask = Map.ActiveProcessorsAffinityMask[Node];
  172. return TRUE;
  173. }
  174. BOOL
  175. WINAPI
  176. GetNumaAvailableMemoryNode(
  177. UCHAR Node,
  178. PULONGLONG AvailableBytes
  179. )
  180. /*++
  181. Routine Description:
  182. This routine returns the (aproximate) amount of memory available
  183. on a given node.
  184. Arguments:
  185. Node Node number for which available memory count is
  186. needed.
  187. AvailableBytes Supplies a pointer to a ULONGLONG in which the
  188. number of bytes of available memory will be
  189. returned.
  190. Return Value:
  191. TRUE is this call was successful, FALSE otherwise.
  192. --*/
  193. {
  194. NTSTATUS Status;
  195. ULONG ReturnedSize;
  196. SYSTEM_NUMA_INFORMATION Memory;
  197. //
  198. // Get the per node available memory table from the system.
  199. //
  200. Status = NtQuerySystemInformation(SystemNumaAvailableMemory,
  201. &Memory,
  202. sizeof(Memory),
  203. &ReturnedSize);
  204. if (!NT_SUCCESS(Status)) {
  205. BaseSetLastNTError(Status);
  206. return FALSE;
  207. }
  208. //
  209. // If the requested node doesn't exist, it doesn't have any
  210. // available memory either.
  211. //
  212. if (Node > Memory.HighestNodeNumber) {
  213. SetLastError(ERROR_INVALID_PARAMETER);
  214. return FALSE;
  215. }
  216. //
  217. // Return the amount of available memory on the requested node.
  218. //
  219. *AvailableBytes = Memory.AvailableMemory[Node];
  220. return TRUE;
  221. }