Implement affinity map bit manipulation and memory sizing helpers
This commit is contained in:
@@ -18,12 +18,23 @@ namespace KE
|
|||||||
class Affinity
|
class Affinity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
STATIC XTFASTCALL VOID AtomicSetProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber);
|
||||||
|
STATIC XTFASTCALL ULONG CalculateAffinityMapSize(IN ULONG CpuCount);
|
||||||
|
STATIC XTFASTCALL BOOLEAN CheckProcessorAffinity(IN PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber);
|
||||||
|
STATIC XTFASTCALL VOID ClearAffinityMap(IN OUT PKAFFINITY_MAP AffinityMap);
|
||||||
|
STATIC XTFASTCALL VOID ClearProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber);
|
||||||
|
|
||||||
STATIC XTAPI VOID CopyAffinity(OUT PKAFFINITY_MAP Destination,
|
STATIC XTAPI VOID CopyAffinity(OUT PKAFFINITY_MAP Destination,
|
||||||
IN PKAFFINITY_MAP Source);
|
IN PKAFFINITY_MAP Source);
|
||||||
STATIC XTAPI ULONG FindNextLeftSetProcessor(IN ULONG ThreadSeed,
|
STATIC XTAPI ULONG FindNextLeftSetProcessor(IN ULONG ThreadSeed,
|
||||||
IN PKAFFINITY_MAP AffinityMap);
|
IN PKAFFINITY_MAP AffinityMap);
|
||||||
STATIC XTAPI ULONG FindNextRightSetProcessor(IN ULONG ThreadSeed,
|
STATIC XTAPI ULONG FindNextRightSetProcessor(IN ULONG ThreadSeed,
|
||||||
IN PKAFFINITY_MAP AffinityMap);
|
IN PKAFFINITY_MAP AffinityMap);
|
||||||
|
STATIC XTFASTCALL VOID SetProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,114 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atomically sets the target processor's affinity bit within the affinity map.
|
||||||
|
*
|
||||||
|
* @param AffinityMap
|
||||||
|
* Supplies a pointer to the affinity map to be modified.
|
||||||
|
*
|
||||||
|
* @param CpuNumber
|
||||||
|
* Supplies the logical processor number to include in the affinity map.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
KE::Affinity::AtomicSetProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber)
|
||||||
|
{
|
||||||
|
/* Atomically set the target CPU bit */
|
||||||
|
RTL::Atomic::Or64((PLONG_PTR)&AffinityMap->Bitmap[CpuNumber / 64], ((KAFFINITY)1 << (CpuNumber % 64)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the memory size required to allocate an affinity map.
|
||||||
|
*
|
||||||
|
* @param CpuCount
|
||||||
|
* Supplies the total number of logical processors the map needs to support.
|
||||||
|
*
|
||||||
|
* @return This routine returns the required allocation bytes.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
ULONG
|
||||||
|
KE::Affinity::CalculateAffinityMapSize(IN ULONG CpuCount)
|
||||||
|
{
|
||||||
|
ULONG AffinitySize, MapSize;
|
||||||
|
|
||||||
|
/* Calculate the required number of blocks and the total structure size */
|
||||||
|
AffinitySize = (CpuCount + 63) / 64;
|
||||||
|
MapSize = sizeof(KAFFINITY_MAP) + (AffinitySize * sizeof(KAFFINITY));
|
||||||
|
|
||||||
|
/* Align the calculated size to an 8-byte boundary */
|
||||||
|
return (MapSize + 7) & ~7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a specific processor is included in the affinity map.
|
||||||
|
*
|
||||||
|
* @param AffinityMap
|
||||||
|
* Supplies a pointer to the affinity map to query.
|
||||||
|
*
|
||||||
|
* @param CpuNumber
|
||||||
|
* Supplies the logical processor number to test.
|
||||||
|
*
|
||||||
|
* @return This routine returns TRUE if the processor's bit is set in the map, or FALSE otherwise.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
BOOLEAN
|
||||||
|
KE::Affinity::CheckProcessorAffinity(IN PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber)
|
||||||
|
{
|
||||||
|
/* Isolate and test the specific bit corresponding to the target CPU */
|
||||||
|
return (AffinityMap->Bitmap[CpuNumber / 64] & ((KAFFINITY)1 << (CpuNumber % 64))) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all processor bindings from the given affinity map.
|
||||||
|
*
|
||||||
|
* @param AffinityMap
|
||||||
|
* Supplies a pointer to the affinity map to be cleared.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
KE::Affinity::ClearAffinityMap(IN OUT PKAFFINITY_MAP AffinityMap)
|
||||||
|
{
|
||||||
|
/* Zero out the entire bitmap */
|
||||||
|
RTL::Memory::ZeroMemory(AffinityMap->Bitmap, AffinityMap->Size * sizeof(KAFFINITY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the affinity bit for a specified processor. This is a non-atomic operation.
|
||||||
|
*
|
||||||
|
* @param AffinityMap
|
||||||
|
* Supplies a pointer to the affinity map to be modified.
|
||||||
|
*
|
||||||
|
* @param CpuNumber
|
||||||
|
* Supplies the logical processor number to exclude from the affinity map.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
KE::Affinity::ClearProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber)
|
||||||
|
{
|
||||||
|
/* Clear the target CPU bit in the affinity map */
|
||||||
|
AffinityMap->Bitmap[CpuNumber / 64] &= ~((KAFFINITY)1 << (CpuNumber % 64));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the topological layout and processor bindings from a source affinity map to a destination map.
|
* Copies the topological layout and processor bindings from a source affinity map to a destination map.
|
||||||
*
|
*
|
||||||
@@ -230,3 +338,25 @@ KE::Affinity::FindNextRightSetProcessor(IN ULONG ThreadSeed,
|
|||||||
/* Fallback to the bootstrap processor */
|
/* Fallback to the bootstrap processor */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the affinity bit for a specified processor. This is a non-atomic operation.
|
||||||
|
*
|
||||||
|
* @param AffinityMap
|
||||||
|
* Supplies a pointer to the affinity map to be modified.
|
||||||
|
*
|
||||||
|
* @param CpuNumber
|
||||||
|
* Supplies the logical processor number to include in the affinity map.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
KE::Affinity::SetProcessorAffinity(IN OUT PKAFFINITY_MAP AffinityMap,
|
||||||
|
IN ULONG CpuNumber)
|
||||||
|
{
|
||||||
|
/* Set the target CPU bit in the affinity map */
|
||||||
|
AffinityMap->Bitmap[CpuNumber / 64] |= ((KAFFINITY)1 << (CpuNumber % 64));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user