//! Thread specific operations.

use crate::error::Result;
use crate::raw::{read, read_mib};

option! {
    allocatedp[ str: b"thread.allocatedp\0", non_str: 2 ] => *mut u64 |
    ops:  |
    docs:
    /// Access to the total number of bytes allocated by the current thread.
    ///
    /// Unlike [`crate::stats::allocated`], the value returned by this type is not the
    /// number of bytes *currently* allocated, but rather the number of bytes
    /// that have *ever* been allocated by this thread.
    ///
    /// The `read` method doesn't return the value directly, but actually a
    /// pointer to the value. This allows for very fast repeated lookup, since
    /// there is no function call overhead. The pointer type cannot be sent to
    /// other threads, but `allocated::read` can be called on different threads
    /// and will return the appropriate pointer for each of them.
    ///
    /// # Example
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// use tikv_jemalloc_ctl::thread;
    /// let allocated = thread::allocatedp::mib().unwrap();
    /// let allocated = allocated.read().unwrap();
    ///
    /// let a = allocated.get();
    /// let buf = vec![0; 1024 * 1024];
    /// let b = allocated.get();
    /// drop(    buf);
    /// let c = allocated.get();
    ///
    /// assert!(a < b);
    /// assert_eq!(b, c);
    /// # }
    /// ```
    mib_docs: /// See [`allocatedp`].
}

impl allocatedp {
    /// Reads value using string API.
    pub fn read() -> Result<ThreadLocal<u64>> {
        unsafe { read(Self::name().as_bytes()).map(ThreadLocal) }
    }
}

impl allocatedp_mib {
    /// Reads value using MIB API.
    pub fn read(&self) -> Result<ThreadLocal<u64>> {
        unsafe { read_mib(self.0.as_ref()).map(ThreadLocal) }
    }
}

option! {
    deallocatedp[ str: b"thread.deallocatedp\0", non_str: 2 ] => *mut u64 |
    ops:  |
    docs:
    /// Access to the total number of bytes deallocated by the current thread.
    ///
    /// The `read` method doesn't return the value directly, but actually a
    /// pointer to the value. This allows for very fast repeated lookup, since
    /// there is no function call overhead. The pointer type cannot be sent to
    /// other threads, but [`deallocatedp::read`] can be called on different
    /// threads and will return the appropriate pointer for each of them.
    ///
    /// # Example
    ///
    /// ```
    /// # #[global_allocator]
    /// # static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
    /// #
    /// # fn main() {
    /// use tikv_jemalloc_ctl::thread;
    /// let deallocated = thread::deallocatedp::mib().unwrap();
    /// let deallocated = deallocated.read().unwrap();
    ///
    /// let a = deallocated.get();
    /// let buf = vec![0; 1024 * 1024];
    /// let b = deallocated.get();
    /// drop(buf);
    /// let c = deallocated.get();
    ///
    /// assert_eq!(a, b);
    /// assert!(b < c);
    /// # }
    /// ```
    mib_docs: /// See [`deallocatedp`].
}

impl deallocatedp {
    /// Reads value using string API.
    pub fn read() -> Result<ThreadLocal<u64>> {
        unsafe { read(Self::name().as_bytes()).map(ThreadLocal) }
    }
}

impl deallocatedp_mib {
    /// Reads value using MIB API.
    pub fn read(&self) -> Result<ThreadLocal<u64>> {
        unsafe { read_mib(self.0.as_ref()).map(ThreadLocal) }
    }
}

/// A thread-local pointer.
///
/// It is neither `Sync` nor `Send`.
// NB we need *const here specifically since it's !Sync + !Send
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct ThreadLocal<T>(*const T);

impl<T> ThreadLocal<T>
where
    T: Copy,
{
    /// Returns the current value at the pointer.
    #[inline]
    pub fn get(self) -> T {
        unsafe { *self.0 }
    }
}
