|
|
/*++
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; }
|