//! `jemalloc` control and introspection.
//!
//! `jemalloc` offers a powerful introspection and control interface through the `mallctl` function.
//! It can be used to tune the allocator, take heap dumps, and retrieve statistics. This crate
//! provides a typed API over that interface.
//!
//! While `mallctl` takes a string to specify an operation (e.g. `stats.allocated` or
//! `stats.arenas.15.muzzy_decay_ms`), the overhead of repeatedly parsing those strings is not
//! ideal. Fortunately, `jemalloc` offers the ability to translate the string ahead of time into a
//! "Management Information Base" (MIB) to speed up future lookups.
//!
//! This crate provides a type for each `mallctl` operation. Calling
//! `$op::{read(), write(x), update(x)}` on the type calls `mallctl` with the
//! string-based API. If the operation will be repeatedly performed, a MIB for
//! the operation can be obtained using `$op.mib()`.
//!
//! # Examples
//!
//! Repeatedly printing allocation statistics:
//!
//! ```no_run
//! use std::thread;
//! use std::time::Duration;
//! use tikv_jemalloc_ctl::{stats, epoch};
//!
//! #[global_allocator]
//! static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
//!
//! fn main() {
//!     loop {
//!         // many statistics are cached and only updated when the epoch is advanced.
//!         epoch::advance().unwrap();
//!
//!         let allocated = stats::allocated::read().unwrap();
//!         let resident = stats::resident::read().unwrap();
//!         println!("{} bytes allocated/{} bytes resident", allocated, resident);
//!         thread::sleep(Duration::from_secs(10));
//!     }
//! }
//! ```
//!
//! Doing the same with the MIB-based API:
//!
//! ```no_run
//! use std::thread;
//! use std::time::Duration;
//! use tikv_jemalloc_ctl::{stats, epoch};
//!
//! #[global_allocator]
//! static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
//!
//! fn main() {
//!     let e = epoch::mib().unwrap();
//!     let allocated = stats::allocated::mib().unwrap();
//!     let resident = stats::resident::mib().unwrap();
//!     loop {
//!         // many statistics are cached and only updated when the epoch is advanced.
//!         e.advance().unwrap();
//!
//!         let allocated = allocated.read().unwrap();
//!         let resident = resident.read().unwrap();
//!         println!("{} bytes allocated/{} bytes resident", allocated, resident);
//!         thread::sleep(Duration::from_secs(10));
//!     }
//! }
//! ```
// TODO: rename the following lint on next minor bump
#![allow(renamed_and_removed_lints)]
#![deny(missing_docs, broken_intra_doc_links)]
#![cfg_attr(not(feature = "use_std"), no_std)]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::module_name_repetitions))]

#[cfg(test)]
#[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

use crate::std::{fmt, mem, num, ops, ptr, result, slice, str};
#[cfg(not(feature = "use_std"))]
use core as std;
#[cfg(feature = "use_std")]
use std;

#[macro_use]
mod macros;

pub mod arenas;
pub mod config;
mod error;
mod keys;
pub mod opt;
pub mod raw;
pub mod stats;
#[cfg(feature = "use_std")]
pub mod stats_print;
pub mod thread;

pub use error::{Error, Result};
pub use keys::{Access, AsName, Mib, MibStr, Name};

option! {
    version[ str: b"version\0", str: 1 ] => &'static str |
    ops: r |
    docs:
    /// `jemalloc` version string.
    ///
    /// # Example
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// use tikv_jemalloc_ctl::version;
    /// println!("jemalloc version {}", version::read().unwrap());
    /// let version_mib = version::mib().unwrap();
    /// println!("jemalloc version {}", version_mib.read().unwrap());
    /// # }
    /// ```
    mib_docs: /// See [`version`].
}

option! {
    background_thread[ str: b"background_thread\0", non_str: 1 ] => bool |
    ops: r,w,u |
    docs:
    /// State of internal background worker threads.
    ///
    /// When enabled, background threads are created on demand (the number of
    /// background threads will be no more than the number of CPUs or active
    /// arenas). Threads run periodically and handle purging asynchronously.
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// # #[cfg(not(target_os = "macos"))] {
    /// #
    /// use tikv_jemalloc_ctl::background_thread;
    /// let bg = background_thread::mib().unwrap();
    /// let s = bg.read().unwrap();
    /// println!("background_threads enabled: {}", s);
    /// let p = background_thread::update(!s).unwrap();
    /// println!("background_threads enabled: {} => {}", p, bg.read().unwrap());
    /// assert_eq!(p, s);
    /// background_thread::write(s).unwrap();
    /// println!("background_threads enabled: {}", bg.read().unwrap());
    /// assert_eq!(p, s);
    /// #
    /// # } // #[cfg(..)]
    /// # }
    /// ```
    mib_docs: /// See [`background_thread`].
}

option! {
    max_background_threads[ str: b"max_background_threads\0", non_str: 1 ] => libc::size_t |
    ops: r, w, u |
    docs:
    /// Maximum number of background threads that will be created.
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// # #[cfg(not(target_os = "macos"))] {
    /// #
    /// use tikv_jemalloc_ctl::max_background_threads;
    /// let m = max_background_threads::mib().unwrap();
    /// println!("max_background_threads: {}", m.read().unwrap());
    /// m.write(2).unwrap();
    /// assert_eq!(m.read().unwrap(), 2);
    /// #
    /// # } // #[cfg(..)]
    /// # }
    /// ```
    mib_docs: /// See [`max_background_threads`].
}

option! {
    epoch[ str: b"epoch\0", non_str: 1 ] => u64 |
    ops: r, w, u |
    docs:
    /// `jemalloc` epoch.
    ///
    /// Many of the statistics tracked by `jemalloc` are cached. The epoch
    /// controls when they are refreshed.
    ///
    /// # Example
    ///
    /// Advancing the epoch:
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// #
    /// use tikv_jemalloc_ctl::epoch;
    /// let e = epoch::mib().unwrap();
    /// let a = e.advance().unwrap();
    /// let b = e.advance().unwrap();
    /// assert_eq!(a + 1, b);
    ///
    /// let o = e.update(0).unwrap();
    /// assert_eq!(o, e.read().unwrap());
    /// # }
    mib_docs: /// See [`epoch`].
}

impl epoch {
    /// Advances the epoch returning its old value - see [`epoch`].
    pub fn advance() -> crate::error::Result<u64> {
        Self::update(1)
    }
}

impl epoch_mib {
    /// Advances the epoch returning its old value - see [`epoch`].
    pub fn advance(self) -> crate::error::Result<u64> {
        self.0.update(1)
    }
}
