[KERNEL32]
authorPierre Schweitzer <pierre@reactos.org>
Sun, 14 Jun 2015 15:52:28 +0000 (15:52 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 14 Jun 2015 15:52:28 +0000 (15:52 +0000)
Implement GetNumaHighestNodeNumber()
Implement GetNumaNodeProcessorMask()
Implement GetNumaProcessorNode()
Implement GetNumaAvailableMemoryNode()

They won't work yet though, given that the kernel mode counterpart is still unimplemented.

CORE-9680

svn path=/trunk/; revision=68136

reactos/dll/win32/kernel32/client/sysinfo.c

index 580f63b..e208755 100644 (file)
@@ -211,50 +211,160 @@ GetLogicalProcessorInformation(OUT PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 GetNumaHighestNodeNumber(OUT PULONG HighestNodeNumber)
 {
-    STUB;
-    return 0;
+    NTSTATUS Status;
+    ULONG Length;
+    ULONG PartialInfo[2]; // First two members of SYSTEM_NUMA_INFORMATION
+
+    /* Query partial NUMA info */
+    Status = NtQuerySystemInformation(SystemNumaProcessorMap,
+                                      PartialInfo,
+                                      sizeof(PartialInfo),
+                                      &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    if (Length < sizeof(ULONG))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* First member of the struct is the highest node number */
+    *HighestNodeNumber = PartialInfo[0];
+    return TRUE;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 GetNumaNodeProcessorMask(IN UCHAR Node,
                          OUT PULONGLONG ProcessorMask)
 {
-    STUB;
-    return 0;
+    NTSTATUS Status;
+    SYSTEM_NUMA_INFORMATION NumaInformation;
+    ULONG Length;
+
+    /* Query NUMA information */
+    Status = NtQuerySystemInformation(SystemNumaProcessorMap,
+                                      &NumaInformation,
+                                      sizeof(NumaInformation),
+                                      &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Validate input node number */
+    if (Node > NumaInformation.HighestNodeNumber)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Return mask for that node */
+    *ProcessorMask = NumaInformation.ActiveProcessorsAffinityMask[Node];
+    return TRUE;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 GetNumaProcessorNode(IN UCHAR Processor,
                      OUT PUCHAR NodeNumber)
 {
-    STUB;
-    return 0;
+    NTSTATUS Status;
+    SYSTEM_NUMA_INFORMATION NumaInformation;
+    ULONG Length;
+    ULONG Node;
+    ULONGLONG Proc;
+
+    /* Can't handle processor number >= 32 */
+    if (Processor >= 0x20)
+    {
+        *NodeNumber = -1;
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Query NUMA information */
+    Status = NtQuerySystemInformation(SystemNumaProcessorMap,
+                                      &NumaInformation,
+                                      sizeof(NumaInformation),
+                                      &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        *NodeNumber = -1;
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Find ourselves */
+    Node = 0;
+    Proc = (1ULL << Processor) >> 0x20;
+    while ((Proc & NumaInformation.ActiveProcessorsAffinityMask[Node]) == 0ULL)
+    {
+        ++Node;
+        /* Out of options */
+        if (Node > NumaInformation.HighestNodeNumber)
+        {
+            *NodeNumber = -1;
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
+        }
+    }
+
+    /* Return found node */
+    *NodeNumber = Node;
+    return TRUE;
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 WINAPI
 GetNumaAvailableMemoryNode(IN UCHAR Node,
                            OUT PULONGLONG AvailableBytes)
 {
-    STUB;
-    return FALSE;
+    NTSTATUS Status;
+    SYSTEM_NUMA_INFORMATION NumaInformation;
+    ULONG Length;
+
+    /* Query NUMA information */
+    Status = NtQuerySystemInformation(SystemNumaAvailableMemory,
+                                      &NumaInformation,
+                                      sizeof(NumaInformation),
+                                      &Length);
+    if (!NT_SUCCESS(Status))
+    {
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* Validate input node number */
+    if (Node > NumaInformation.HighestNodeNumber)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Return available memory for that node */
+    *AvailableBytes = NumaInformation.AvailableMemory[Node];
+    return TRUE;
 }
 
 /*