1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//! The one `#[global_allocator]` for every ZisK binary.
//!
//! `#[global_allocator]` may be declared in a library and applies to whichever
//! binary links it, and only one may exist per binary — declaring it here
//! rather than in each `main.rs` is what keeps `cargo-zisk`, `cargo-zisk-dev`
//! and `zisk-worker` from conflicting.
//!
//! **Why replace glibc's allocator.** glibc serves the 128 KB-32 MB collector
//! buffers from per-thread arenas. A buffer freed by a thread on one arena is
//! invisible to threads bound to another, and an arena never shrinks, so the
//! capacity accumulates across jobs. Measured on a worker over 18 jobs: glibc's
//! arena grew +12.6 GB while the bytes actually in use stayed flat at ~750 MB —
//! **96% of the growth was memory already freed**. jemalloc instead returns
//! memory to the OS on a decay timer.
/// jemalloc, replacing the system allocator for every binary linking this crate.
static GLOBAL_ALLOC: Jemalloc = Jemalloc;
/// Compile-time jemalloc configuration, overridable at runtime by the
/// `MALLOC_CONF` environment variable so settings can be swept without
/// rebuilding.
///
/// Only `background_thread` is set, and only because its default (`false`) is
/// unhelpful here: it makes jemalloc purge dirty pages from a background thread
/// rather than only during allocator calls, and the worker is idle between jobs
/// — exactly when we want pages handed back.
///
/// `narenas` is deliberately **not** capped. That would transplant the glibc
/// `MALLOC_ARENA_MAX` workaround onto an allocator without glibc's per-thread
/// retention problem, and risks contention across the ~250 threads the witness
/// phase runs.
pub static MALLOC_CONF: & = b"background_thread:true\0";