numa-shim 0.1.0

100% Rust NUMA detection and binding — no C/C++ libraries (no libnuma, no hwloc). Linux mbind(2) via raw syscall(2), Windows VirtualAllocExNuma, sysfs cpumap reader. macOS/miri no-op. Zero crate deps by default. forbid(unsafe_code)-friendly for consumers.
Documentation
  • Coverage
  • 100%
    4 out of 4 items documented1 out of 3 items with examples
  • Size
  • Source code size: 57.84 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 333.03 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 5s Average build duration of successful builds.
  • all releases: 5s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • PHPCraftdream/sefer-alloc
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • PHPCraftdream

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) via syscall(number, ...) — the number is baked in as a constant (SYS_MBIND = 237 on x86_64, 235 on aarch64). No libnuma symbol needed; syscall(2) is always present in glibc and musl.
  • Linux node detection: reads /sys/devices/system/node/nodeN/cpumap via POSIX open/read/close with no heap allocation (stack buffer only).
  • Windows: Win32 APIs from kernel32.dll — always linked, no extra import lib.

Usage

[dependencies]
numa-shim = "0.1"

# Optional: enables reserve_on_node() which wraps aligned-vmem
# numa-shim = { version = "0.1", features = ["vmem-integration"] }
use numa_shim::{current_node, bind_range, NO_NODE};

// Detect the current thread's NUMA node.
match current_node() {
    Some(node) => println!("on NUMA node {node}"),
    None       => println!("NUMA unavailable"),
}

// Bind a live allocation to a NUMA node (Linux: mbind; Windows/macOS: no-op).
let mut buf = vec![0u8; 4096];
let node = current_node().unwrap_or(0);
// SAFETY: `buf` is a live allocation owned by this scope.
unsafe { bind_range(buf.as_mut_ptr(), buf.len(), node) };

Feature flags

vmem-integration

Enables [reserve_on_node], which reserves aligned anonymous virtual memory with a NUMA preference using aligned-vmem:

use numa_shim::{reserve_on_node, current_node};
use aligned_vmem::PAGE;

let node = current_node().unwrap_or(0);
let r = reserve_on_node(PAGE * 16, PAGE, node).expect("OOM");
// 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 = u32::MAX;

/// NUMA node of the calling thread, or None if unavailable.
pub fn current_node() -> Option<u32>;

/// 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 fn bind_range(base: *mut u8, len: usize, node: u32);

/// Reserve aligned anonymous memory with NUMA preference (feature = "vmem-integration").
#[cfg(feature = "vmem-integration")]
pub fn reserve_on_node(size: usize, align: usize, node: u32) -> Option<aligned_vmem::Reservation>;

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