From 0680a926e055829b0fad30ba8e4bb57f05923f70 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 14 Jun 2015 15:52:28 +0000 Subject: [PATCH] [KERNEL32] 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 | 134 ++++++++++++++++++-- 1 file changed, 122 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/sysinfo.c b/reactos/dll/win32/kernel32/client/sysinfo.c index 580f63b10c7..e208755990b 100644 --- a/reactos/dll/win32/kernel32/client/sysinfo.c +++ b/reactos/dll/win32/kernel32/client/sysinfo.c @@ -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; } /*