Processor Affinity

There was a time when 32 processors for 32-bit Windows seemed, if not beyond
conception, then surely beyond dreaming about as ever being a real-world experience.
And so from the start, Windows tracked its use of processors for various purposes—which
processors are active, which processors is this thread allowed to run on—just as
set or clear bits in an integer type as wide as a general register. The Device Driver
Kit (DDK) for Windows NT 3.51 has

typedef ULONG KAFFINITY;

which the DDK for Windows XP modified to

typedef ULONG_PTR KAFFINITY;

in anticipation of 64-bit Windows. And there things stood until Windows 7 introduced
the processor group as a soft path to supporting potentially very many more processors.
For many purposes, the use of processors is confined to one group, which can be
taken as understood, so that the simple KAFFINITY remains
perfectly well suited to tracking the use. For cases where the group must be specified,
Microsoft introduced the GROUP_AFFINITY structure and
some exported functions for working with it:

KeAddProcessorGroupAffinity

KeCheckProcessorGroupAffinity

KeCountSetBitsGroupAffinity

KeFindFirstSetLeftGroupAffinity

KeFindFirstSetRightGroupAffinity

KeProcessorGroupAffinity

KeRemoveProcessorGroupAffinity

For its internal accounting, however, the kernel does of course need a bitmap
of all processors in all groups. For this, it has the undocumented
KAFFINITY_EX structure
and a set of exported functions for working with it so that it can (mostly) be kept
opaque:

KeAddGroupAffinityEx

KeAddProcessorAffinityEx

KeAndAffinityEx

KeAndGroupAffinityEx

KeCheckProcessorAffinityEx

KeComplementAffinityEx

KeCopyAffinityEx

KeCountSetBitsAffinityEx

KeFindFirstSetLeftAffinityEx

KeFindFirstSetRightAffinityEx (6.3 and higher)

KeFirstGroupAffinityEx

KeInitializeAffinityEx

KeInterlockedClearProcessorAffinityEx

KeInterlockedSetProcessorAffinityEx

KeIsEmptyAffinityEx

KeIsEqualAffinityEx

KeIsSingleGroupAffinityEx

KeIsSubsetAffinityEx

KeOrAffinityEx

KeQueryGroupAffinityEx

KeRemoveGroupAffinityEx

KeRemoveProcessorAffinityEx

KeSubtractAffinityEx

For the limited but common purpose of enumerating the set bits, the kernel has
the undocumented KAFFINITY_ENUMERATION_CONTEXT, again
with supporting functions:

KeEnumerateNextProcessor

KeInitializeEnumerationContext

KeInitializeEnumerationContextFromAffinity (10.0
and higher)

KeInitializeEnumerationContextFromGroup

None of the few dozen functions listed above are documented. All are declared,
however, in the NTOSP.H from the Windows Driver Kit (WDK) for Windows 10.