numa-shim
100 % Rust NUMA detection and binding — no C / C++ libraries.
The key differentiator: zero C / C++ crate dependencies — no libnuma, no
hwloc, no libcuda. Only the system libc / kernel32 syscalls that any
Rust program already links to.
| Platform | Node detection | Memory binding |
|---|---|---|
| Linux x86_64 / aarch64 | sched_getcpu + sysfs /sys/devices/system/node/nodeN/cpumap |
mbind(2) via raw syscall(2) — no libnuma, no hwloc |
| Windows | GetCurrentProcessorNumberEx + GetNumaProcessorNodeEx |
VirtualAllocExNuma (via vmem-integration feature) |
| macOS | not available (no public NUMA API) | no-op |
| miri | not available | no-op |
Why yet another NUMA crate?
Most Rust NUMA crates link to libnuma or hwloc, pulling in heavy C
dependencies that complicate cross-compilation and static linking. numa-shim
calls the kernel directly:
- Linux:
mbind(2)viasyscall(number, ...)— the number is baked in as a constant (SYS_MBIND = 237on x86_64,235on aarch64). Nolibnumasymbol needed;syscall(2)is always present in glibc and musl. - Linux node detection: reads
/sys/devices/system/node/nodeN/cpumapvia POSIXopen/read/closewith no heap allocation (stack buffer only). - Windows: Win32 APIs from
kernel32.dll— always linked, no extra import lib.
Usage
[]
= "0.1"
# Optional: enables reserve_on_node() which wraps aligned-vmem
# numa-shim = { version = "0.1", features = ["vmem-integration"] }
use ;
// Detect the current thread's NUMA node.
match current_node
// Bind a live allocation to a NUMA node (Linux: mbind; Windows/macOS: no-op).
let mut buf = vec!;
let node = current_node.unwrap_or;
// SAFETY: `buf` is a live allocation owned by this scope.
unsafe ;
Feature flags
vmem-integration
Enables [reserve_on_node], which reserves aligned anonymous virtual memory
with a NUMA preference using aligned-vmem:
use ;
use PAGE;
let node = current_node.unwrap_or;
let r = reserve_on_node.expect;
// r is an `aligned_vmem::Reservation` — RAII, drops cleanly.
Without this feature, numa-shim has zero runtime dependencies.
Public API
/// Sentinel: no NUMA node / unsupported platform.
pub const NO_NODE: u32 = u32MAX;
/// NUMA node of the calling thread, or None if unavailable.
;
/// Bind [base, base+len) to a NUMA node (Linux: mbind; others: no-op).
/// # Safety
/// [base, base+len) must be a valid OS reservation owned by the caller.
pub unsafe ;
/// Reserve aligned anonymous memory with NUMA preference (feature = "vmem-integration").
;
Linux syscall numbers
| Architecture | SYS_MBIND |
|---|---|
| x86_64 | 237 |
| aarch64 | 235 |
On other Linux architectures bind_range is a documented no-op (the syscall
number is unknown; contributions welcome).
MSRV
Rust 1.88
License
MIT OR Apache-2.0