From a5ae9ea58879b9998e4632075e8ad96de3f366b0 Mon Sep 17 00:00:00 2001 From: dawn <90008@klbr.net> Date: Tue, 6 Oct 2026 16:30:18 +0300 Subject: [PATCH] [ffi] let an embedder opt into jemalloc hydrant-ffi turns hydrant's default features off, so an embedded hydrant always ran on the embedding program's malloc, glibc for spindle on nixos, and never on the tuned jemalloc the binary uses. the new alloc-jemalloc feature, off by default, pulls in the same src/allocator.rs the binary and the benches use, linux tuning included. tikv-jemallocator's symbols are prefixed (_rjem_*), so with it on the staticlib carries jemalloc for hydrant's own rust allocations and defines no plain malloc, so the program's allocator is left alone. with it off the allocator module is empty and the library is the same as before. --- Cargo.lock | 1 + docs/embedding.md | 2 ++ ffi/Cargo.toml | 11 ++++++++++- ffi/src/lib.rs | 3 +++ src/allocator.rs | 4 ++-- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 989c8a0..7fa0c06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1671,6 +1671,7 @@ dependencies = [ "hydrant", "miette", "serde_json", + "tikv-jemallocator", "tokio", "tracing-subscriber", ] diff --git a/docs/embedding.md b/docs/embedding.md index ad057b6..037ec2c 100644 --- a/docs/embedding.md +++ b/docs/embedding.md @@ -14,6 +14,8 @@ cargo build --release -p hydrant-ffi this produces the static library `libhydrant_ffi.a` in `target/release` (or `target//release` when a target is set). the header is `ffi/include/hydrant.h`. +by default hydrant allocates with the program's own malloc. add `--features alloc-jemalloc` to give it the same tuned jemalloc the binary uses instead. its symbols are prefixed (`_rjem_*`), so only hydrant's allocations move to it and the program's malloc stays as it was. + ## settings `hydrant_start` takes a json object with the same settings the binary reads from its environment (see [configuration](configuration.md)), plus `RUST_LOG`. the process environment and any `.env` file are ignored, so the embedding program's own environment can't leak in. diff --git a/ffi/Cargo.toml b/ffi/Cargo.toml index 6edac16..70237cb 100644 --- a/ffi/Cargo.toml +++ b/ffi/Cargo.toml @@ -7,10 +7,19 @@ publish = false [lib] crate-type = ["staticlib"] +[features] +# off by default because the embedding program owns the process, allocator included. its +# symbols are prefixed, so turning it on never swaps out the embedder's own malloc +alloc-jemalloc = ["dep:tikv-jemallocator"] + [dependencies] -# no allocator features, because the embedding program owns the process, its allocator included hydrant = { path = "..", default-features = false, features = ["indexer", "indexer_stream"] } tokio = { version = "1.0", features = ["rt-multi-thread"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] } serde_json = "1.0" miette = "7" +tikv-jemallocator = { version = "0.6", optional = true } + +[lints.rust] +# src/allocator.rs is shared with the binary, which has these too +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("alloc-mimalloc", "alloc-snmalloc"))'] } diff --git a/ffi/src/lib.rs b/ffi/src/lib.rs index 766ef94..eb0b947 100644 --- a/ffi/src/lib.rs +++ b/ffi/src/lib.rs @@ -16,6 +16,9 @@ use hydrant::config::Config; use hydrant::control::{ApiBinds, Hydrant}; use hydrant::deps::futures::FutureExt; +#[path = "../../src/allocator.rs"] +mod allocator; + /// a hydrant started by `hydrant_start`, until `hydrant_free`. pub struct HydrantHandle { exit: Arc, diff --git a/src/allocator.rs b/src/allocator.rs index 10f52d3..a9a05f4 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,5 +1,5 @@ -//! the global allocator, picked by the `alloc-*` features. the hydrant binary and the benches -//! both include this file, so benchmarks allocate the way production does. +//! the global allocator, picked by the `alloc-*` features. the hydrant binary, the benches and +//! hydrant-ffi all include this file, so benchmarks allocate the way production does. #[cfg(feature = "alloc-mimalloc")] #[global_allocator] -- 2.51.2