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]