use std::cell::Cell;
use std::sync::atomic::{AtomicU64, Ordering};
static REFLINKED_BYTES: AtomicU64 = AtomicU64::new(0);
static HARDLINKED_BYTES: AtomicU64 = AtomicU64::new(0);
static COPIED_BYTES: AtomicU64 = AtomicU64::new(0);
thread_local! {
static THREAD_REFLINKED: Cell<u64> = const { Cell::new(0) };
static THREAD_COPIED: Cell<u64> = const { Cell::new(0) };
}
pub fn record_reflinked(bytes: u64) {
REFLINKED_BYTES.fetch_add(bytes, Ordering::Relaxed);
THREAD_REFLINKED.with(|slot| slot.set(slot.get() + bytes));
}
pub fn record_hardlinked(bytes: u64) {
HARDLINKED_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_copied(bytes: u64) {
COPIED_BYTES.fetch_add(bytes, Ordering::Relaxed);
THREAD_COPIED.with(|slot| slot.set(slot.get() + bytes));
}
pub fn reflinked_bytes() -> u64 {
REFLINKED_BYTES.load(Ordering::Relaxed)
}
pub fn hardlinked_bytes() -> u64 {
HARDLINKED_BYTES.load(Ordering::Relaxed)
}
pub fn copied_bytes() -> u64 {
COPIED_BYTES.load(Ordering::Relaxed)
}
pub fn thread_reflinked_bytes() -> u64 {
THREAD_REFLINKED.with(Cell::get)
}
pub fn thread_copied_bytes() -> u64 {
THREAD_COPIED.with(Cell::get)
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub struct StoreThreadBytes {
pub reflinked: u64,
pub hardlinked: u64,
pub copied: u64,
pub copy_cross_device: u64,
pub copy_permission: u64,
pub copy_ineligible: u64,
pub copy_other: u64,
}
thread_local! {
static STORE_THREAD_BYTES: std::cell::Cell<StoreThreadBytes> =
std::cell::Cell::new(StoreThreadBytes::default());
}
pub fn store_thread_bytes() -> StoreThreadBytes {
STORE_THREAD_BYTES.with(std::cell::Cell::get)
}
static STORE_REFLINKED_BYTES: AtomicU64 = AtomicU64::new(0);
static STORE_HARDLINKED_BYTES: AtomicU64 = AtomicU64::new(0);
static STORE_COPIED_BYTES: AtomicU64 = AtomicU64::new(0);
pub fn record_store_reflinked(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.reflinked += bytes;
counter.set(value);
});
STORE_REFLINKED_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_store_hardlinked(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.hardlinked += bytes;
counter.set(value);
});
STORE_HARDLINKED_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_store_copied(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.copied += bytes;
counter.set(value);
});
STORE_COPIED_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn store_reflinked_bytes() -> u64 {
STORE_REFLINKED_BYTES.load(Ordering::Relaxed)
}
pub fn store_hardlinked_bytes() -> u64 {
STORE_HARDLINKED_BYTES.load(Ordering::Relaxed)
}
pub fn store_copied_bytes() -> u64 {
STORE_COPIED_BYTES.load(Ordering::Relaxed)
}
static STORE_COPY_CROSS_DEVICE_BYTES: AtomicU64 = AtomicU64::new(0);
static STORE_COPY_PERMISSION_BYTES: AtomicU64 = AtomicU64::new(0);
static STORE_COPY_INELIGIBLE_BYTES: AtomicU64 = AtomicU64::new(0);
static STORE_COPY_OTHER_BYTES: AtomicU64 = AtomicU64::new(0);
static RESTORE_COPY_CROSS_DEVICE_BYTES: AtomicU64 = AtomicU64::new(0);
static RESTORE_COPY_PERMISSION_BYTES: AtomicU64 = AtomicU64::new(0);
static RESTORE_COPY_EXCLUSIVE_BYTES: AtomicU64 = AtomicU64::new(0);
static RESTORE_COPY_OTHER_BYTES: AtomicU64 = AtomicU64::new(0);
pub fn record_store_copy_cross_device(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.copy_cross_device += bytes;
counter.set(value);
});
STORE_COPY_CROSS_DEVICE_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_store_copy_permission(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.copy_permission += bytes;
counter.set(value);
});
STORE_COPY_PERMISSION_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_store_copy_ineligible(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.copy_ineligible += bytes;
counter.set(value);
});
STORE_COPY_INELIGIBLE_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_store_copy_other(bytes: u64) {
STORE_THREAD_BYTES.with(|counter| {
let mut value = counter.get();
value.copy_other += bytes;
counter.set(value);
});
STORE_COPY_OTHER_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_restore_copy_cross_device(bytes: u64) {
RESTORE_COPY_CROSS_DEVICE_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_restore_copy_permission(bytes: u64) {
RESTORE_COPY_PERMISSION_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
#[cfg(unix)]
pub fn record_restore_copy_exclusive(bytes: u64) {
RESTORE_COPY_EXCLUSIVE_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn record_restore_copy_other(bytes: u64) {
RESTORE_COPY_OTHER_BYTES.fetch_add(bytes, Ordering::Relaxed);
}
pub fn store_copy_cross_device_bytes() -> u64 {
STORE_COPY_CROSS_DEVICE_BYTES.load(Ordering::Relaxed)
}
pub fn store_copy_permission_bytes() -> u64 {
STORE_COPY_PERMISSION_BYTES.load(Ordering::Relaxed)
}
pub fn store_copy_ineligible_bytes() -> u64 {
STORE_COPY_INELIGIBLE_BYTES.load(Ordering::Relaxed)
}
pub fn store_copy_other_bytes() -> u64 {
STORE_COPY_OTHER_BYTES.load(Ordering::Relaxed)
}
pub fn restore_copy_cross_device_bytes() -> u64 {
RESTORE_COPY_CROSS_DEVICE_BYTES.load(Ordering::Relaxed)
}
pub fn restore_copy_permission_bytes() -> u64 {
RESTORE_COPY_PERMISSION_BYTES.load(Ordering::Relaxed)
}
pub fn restore_copy_exclusive_bytes() -> u64 {
RESTORE_COPY_EXCLUSIVE_BYTES.load(Ordering::Relaxed)
}
pub fn restore_copy_other_bytes() -> u64 {
RESTORE_COPY_OTHER_BYTES.load(Ordering::Relaxed)
}