Man, going crazy here.
If you’re writing a library which fully supports pre-allocaton (e.g. does no allocation of its own) then NUMA is a complete, humungous pain in the ass.
Consider SMR. To be NUMA aware and performant, I keep a thread SMR state list and a spare release callback thread SMR state per NUMA node. So the user needs to know how many NUMA nodes there are, then allocate an array of pointers to SMR NUMA state, allocate state once for each NUMA node (on the respective nodes), then pass that into the SMR init function, along with the SMR state, for initialization.
Then later when a user inits a new thread SMR state, he has to indicate which NUMA node it is allocated in, so that it goes into the correct list.
This means both the user and library have to know about NUMA nodes and have to agree on a way of communicating about them. It’s all very well the user making for SMR state init an alloc per NUMA node, but how does he know what NUMA nodes exist and how do I know which allocs are for which NUMA node?
I don’t want to place on users a burden of having to learn about and write up a bunch of NUMA code, to be able to use liblfds.
However… anyone on a non-NUMA system can simply indicate NUMA node 0, always. So that’s okay.
Users who *are* using NUMA will already be prepared to do NUMA work. The issue then is communicating meaningfully about NUMA node numbers. On Windows, NUMA nodes seem to have arbitrary integer IDs. On Linux, there’s a bitmask, so they all have power of two IDs.
So, I guess the answer is; if you don’t have NUMA, indicate NUMA node 0. If you do, then I expect you to be able to know what NUMA nodes you have, to make allocations on them and to indicate to me their node numbers.
That means then that the library doesn’t have to provide an API to find the NUMA node numbers for the user; all it has to do is accept numbers from the user and assume they’re true.
Okay… let’s see how that rolls.