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
307 lines
6.5 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
numa.c
|
|
|
|
Abstract:
|
|
|
|
This module implements Win32 Non Uniform Memory Architecture
|
|
information APIs.
|
|
|
|
Author:
|
|
|
|
Peter Johnston (peterj) 21-Sep-2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "basedll.h"
|
|
|
|
BOOL
|
|
WINAPI
|
|
GetNumaHighestNodeNumber(
|
|
PULONG HighestNodeNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return the (current) highest numbered node in the system.
|
|
|
|
Arguments:
|
|
|
|
HighestNodeNumber Supplies a pointer to receive the number of
|
|
last (highest) node in the system.
|
|
|
|
Return Value:
|
|
|
|
TRUE unless something impossible happened.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ReturnedSize;
|
|
ULONGLONG Information;
|
|
PSYSTEM_NUMA_INFORMATION Numa;
|
|
|
|
Numa = (PSYSTEM_NUMA_INFORMATION)&Information;
|
|
|
|
Status = NtQuerySystemInformation(SystemNumaProcessorMap,
|
|
Numa,
|
|
sizeof(Information),
|
|
&ReturnedSize);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// This can't possibly happen. Attempt to handle it
|
|
// gracefully.
|
|
//
|
|
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
if (ReturnedSize < sizeof(ULONG)) {
|
|
|
|
//
|
|
// Nor can this.
|
|
//
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Return the number of nodes in the system.
|
|
//
|
|
|
|
*HighestNodeNumber = Numa->HighestNodeNumber;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
GetNumaProcessorNode(
|
|
UCHAR Processor,
|
|
PUCHAR NodeNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return the Node number for a given processor.
|
|
|
|
Arguments:
|
|
|
|
Processor Supplies the processor number.
|
|
NodeNumber Supplies a pointer to the UCHAR to receive the
|
|
node number this processor belongs to.
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if function succeeded, FALSE if it failed. If it
|
|
failed because the processor wasn't present, then set the
|
|
NodeNumber to 0xFF
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONGLONG Mask;
|
|
NTSTATUS Status;
|
|
ULONG ReturnedSize;
|
|
UCHAR Node;
|
|
SYSTEM_NUMA_INFORMATION Map;
|
|
|
|
//
|
|
// If the requested processor number is not reasonable, return
|
|
// error value.
|
|
//
|
|
|
|
if (Processor >= MAXIMUM_PROCESSORS) {
|
|
*NodeNumber = 0xFF;
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Get the Node -> Processor Affinity map from the system.
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(SystemNumaProcessorMap,
|
|
&Map,
|
|
sizeof(Map),
|
|
&ReturnedSize);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// This can't happen,... but try to stay sane if possible.
|
|
//
|
|
|
|
*NodeNumber = 0xFF;
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Look thru the nodes returned for the node in which the
|
|
// requested processor's affinity is non-zero.
|
|
//
|
|
|
|
Mask = 1 << Processor;
|
|
|
|
for (Node = 0; Node <= Map.HighestNodeNumber; Node++) {
|
|
if ((Map.ActiveProcessorsAffinityMask[Node] & Mask) != 0) {
|
|
*NodeNumber = Node;
|
|
return TRUE;
|
|
}
|
|
}
|
|
//
|
|
// Didn't find this processor in any node, return error value.
|
|
//
|
|
|
|
*NodeNumber = 0xFF;
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
GetNumaNodeProcessorMask(
|
|
UCHAR Node,
|
|
PULONGLONG ProcessorMask
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is used to obtain the bitmask of processors for a
|
|
given node.
|
|
|
|
Arguments:
|
|
|
|
Node Supplies the Node number for which the set of
|
|
processors is returned.
|
|
ProcessorMask Pointer to a ULONGLONG to receivethe bitmask of
|
|
processors on this node.
|
|
|
|
Return Value:
|
|
|
|
TRUE is the Node number was reasonable, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ReturnedSize;
|
|
SYSTEM_NUMA_INFORMATION Map;
|
|
|
|
//
|
|
// Get the node -> processor mask table from the system.
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(SystemNumaProcessorMap,
|
|
&Map,
|
|
sizeof(Map),
|
|
&ReturnedSize);
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// This can't possibly have happened.
|
|
//
|
|
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the requested node doesn't exist, return a zero processor
|
|
// mask.
|
|
//
|
|
|
|
if (Node > Map.HighestNodeNumber) {
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Return the processor mask for the requested node.
|
|
//
|
|
|
|
*ProcessorMask = Map.ActiveProcessorsAffinityMask[Node];
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
GetNumaAvailableMemoryNode(
|
|
UCHAR Node,
|
|
PULONGLONG AvailableBytes
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the (aproximate) amount of memory available
|
|
on a given node.
|
|
|
|
Arguments:
|
|
|
|
Node Node number for which available memory count is
|
|
needed.
|
|
AvailableBytes Supplies a pointer to a ULONGLONG in which the
|
|
number of bytes of available memory will be
|
|
returned.
|
|
|
|
Return Value:
|
|
|
|
TRUE is this call was successful, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ReturnedSize;
|
|
SYSTEM_NUMA_INFORMATION Memory;
|
|
|
|
//
|
|
// Get the per node available memory table from the system.
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(SystemNumaAvailableMemory,
|
|
&Memory,
|
|
sizeof(Memory),
|
|
&ReturnedSize);
|
|
if (!NT_SUCCESS(Status)) {
|
|
BaseSetLastNTError(Status);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// If the requested node doesn't exist, it doesn't have any
|
|
// available memory either.
|
|
//
|
|
|
|
if (Node > Memory.HighestNodeNumber) {
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Return the amount of available memory on the requested node.
|
|
//
|
|
|
|
*AvailableBytes = Memory.AvailableMemory[Node];
|
|
return TRUE;
|
|
}
|