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
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.

//! This crate controls the global allocator used by TiKV.
//!
//! As of now TiKV always turns on jemalloc on Unix, though libraries
//! generally shouldn't be opinionated about their allocators like
//! this. It's easier to do this in one place than to have all our
//! bins turn it on themselves.
//!
//! Writing `extern crate tikv_alloc;` will link it to jemalloc when
//! appropriate. The TiKV library itself links to `tikv_alloc` to
//! ensure that any binary linking to it will use jemalloc.
//!
//! With few exceptions, _every binary and project in the TiKV workspace
//! should link (perhaps transitively) to tikv_alloc_. This is to ensure
//! that tests and benchmarks run with the production allocator. In other
//! words, binaries and projects that don't link to `tikv` should link
//! to `tikv_alloc`.
//!
//! At present all Unixes use jemalloc, and others don't. Whichever
//! allocator is used, this crate presents the same API, and some
//! profiling functions become no-ops. Note however that _not all
//! platforms override C malloc, including macOS_. This means on some
//! platforms RocksDB is using the system malloc. On Linux C malloc is
//! redirected to jemalloc.
//!
//! This crate accepts two cargo features:
//!
//! - mem-profiling - compiles jemalloc and this crate with profiling
//!   capability
//!
//! - jemalloc - compiles tikv-jemallocator (default)
//!
//! - tcmalloc - compiles tcmalloc
//!
//! cfg `fuzzing` is defined by `run_libfuzzer` in `fuzz/cli.rs` and
//! is passed to rustc directly with `--cfg`; in other words it's not
//! controlled through a crate feature.
//!
//! Ideally there should be no jemalloc-specific code outside this
//! crate.
//!
//! # Profiling
//!
//! Profiling with jemalloc requires both build-time and run-time
//! configuration. At build time cargo needs the `--mem-profiling`
//! feature, and at run-time jemalloc needs to set the `opt.prof`
//! option to true, ala `MALLOC_CONF="opt.prof:true".
//!
//! In production you might also set `opt.prof_active` to `false` to
//! keep profiling off until there's an incident. Jemalloc has
//! a variety of run-time [profiling options].
//!
//! [profiling options]: http://jemalloc.net/jemalloc.3.html#opt.prof
//!
//! Here's an example of how you might build and run via cargo, with
//! profiling:
//!
//! ```notrust
//! export MALLOC_CONF="prof:true,prof_active:false,prof_prefix:$(pwd)/jeprof"
//! cargo test --features mem-profiling -p tikv_alloc -- --ignored
//! ```
//!
//! (In practice you might write this as a single statement, setting
//! `MALLOC_CONF` only temporarily, e.g. `MALLOC_CONF="..." cargo test
//! ...`).
//!
//! When running cargo while `prof:true`, you will see messages like
//!
//! ```notrust
//! <jemalloc>: Invalid conf pair: prof:true
//! <jemalloc>: Invalid conf pair: prof_active:false
//! ```
//!
//! This is normal - they are being emitting by the jemalloc in cargo
//! and rustc, which are both configured without profiling. TiKV's
//! jemalloc is configured for profiling if you pass
//! `--features=mem-profiling` to cargo for eather `tikv_alloc` or
//! `tikv`.

#[cfg(feature = "mem-profiling")]
#[macro_use]
extern crate log;

#[cfg(feature = "jemalloc")]
#[macro_use]
extern crate lazy_static;

pub mod error;
pub mod trace;

#[cfg(not(all(unix, not(fuzzing), feature = "jemalloc")))]
mod default;

pub type AllocStats = Vec<(&'static str, usize)>;

// Allocators
#[cfg(all(unix, not(fuzzing), feature = "jemalloc"))]
#[path = "jemalloc.rs"]
mod imp;
#[cfg(all(unix, not(fuzzing), feature = "tcmalloc"))]
#[path = "tcmalloc.rs"]
mod imp;
#[cfg(all(unix, not(fuzzing), feature = "mimalloc"))]
#[path = "mimalloc.rs"]
mod imp;
#[cfg(not(all(
    unix,
    not(fuzzing),
    any(feature = "jemalloc", feature = "tcmalloc", feature = "mimalloc")
)))]
#[path = "system.rs"]
mod imp;

pub use crate::imp::*;

#[global_allocator]
static ALLOC: imp::Allocator = imp::allocator();