I need some means to allocate different things from different memory pools or different heaps.
when I allocate an object - I need to allocate it from a specific region or pool of memory.
The practical example is: I have a multi-core system (not something like a QuadCore CPU - something else) - there is a big fat "quad-core ARM64" that is the main processor
But each SUB processor gets its own 64MEG region of memory - If the message is for CPU A, I need to allocate from the CPU A memory space, same for CPU B and CPU C they would allocate various structures from different pools.
How can I specify what pool a RUST struct comes from? I can manage releasing the structure thats easy.
Memory allocation on a NUMA system usually works like this: When an application allocates memory from the OS (via syscall), then the OS only reserves virtual addresses for that memory block, but it does not yet allocate the physical memory pages. Only when the memory block is actually accessed for the first time, this will trigger a trap (page fault) and the OS then allocates physical memory pages – locally at the specific processor who performs this first access.
I think these kinds of things are implemented in the OS kernel and are out of control of an application (user space code) – regardless of whether that application is written in Rust, or C or whatever programming language. So, unless you actually write your own OS kernel (or want to contribute to an existing OS kernel) these are not things you need to be concerned about.
Specifically, Rust allows you to set a custom memory allocator with the #[global_allocator] attribute. But any allocator ultimately has to request memory blocks that it can work with from the underlying operating system – by using syscalls, such as mmap on a Linux/Unix systems, or VirtualAlloc on a Windows system. And the OS only ever provides blocks (ranges) of virtual addresses to the application (or to the allocator)! Mapping these virtual addresses to actual physical memory pages is handled internally by the OS kernel, and thus is not your concern.
Rust-the-language doesn't allocate anything. Structs are created as values (typically on the stack). This is the total opposite of objects in languages like Java.
So for most instances of most types there's nothing to specify at creation time.
Standard library types allocate: Box, Vec, String, etc. These all use one global allocator. You can set your own allocator, but it will have to work for all std types and allow moving allocations between threads.
There's a plan to make standard library support multiple different allocators, but that's not stabilized yet.
You can make your own types replacing Vec and other heap data structures, and then allocate their storage however you want. There are low-level primitives like core::ptr::write and drop_in_place, MaybeUninit, ManuallyDrop for managing lifetime of arbitrary types inside custom allocations.
You might be interested in my pstd crate, it allows working with the usual Rust containers Vec, BTreeMap, String etc. (well look-alikes) but allocated in different ways. This is on stable.