#![allow(dead_code)]
use std::sync::atomic::{AtomicBool, Ordering};
static TRACE: AtomicBool = AtomicBool::new(false);
pub fn set_enabled(on: bool) {
TRACE.store(on, Ordering::Relaxed);
}
pub fn enabled() -> bool {
TRACE.load(Ordering::Relaxed)
}
fn rss_mb() -> u64 {
#[cfg(target_os = "linux")]
{
match std::fs::read_to_string("/proc/self/statm") {
Ok(s) => {
let resident_pages: u64 = s
.split_whitespace()
.nth(1)
.and_then(|f| f.parse().ok())
.unwrap_or(0);
resident_pages * 4096 / (1024 * 1024)
}
Err(_) => 0,
}
}
#[cfg(all(not(target_os = "linux"), unix))]
{
let mut ru = unsafe { std::mem::zeroed::<libc::rusage>() };
if unsafe { libc::getrusage(libc::RUSAGE_SELF, &mut ru) } == 0 {
ru.ru_maxrss as u64 / (1024 * 1024)
} else {
0
}
}
#[cfg(not(any(target_os = "linux", unix)))]
{
0
}
}
fn peak_mb() -> u64 {
#[cfg(target_os = "linux")]
{
match std::fs::read_to_string("/proc/self/status") {
Ok(s) => s
.lines()
.find_map(|l| l.strip_prefix("VmHWM:"))
.and_then(|v| v.split_whitespace().next())
.and_then(|kb| kb.parse::<u64>().ok())
.map(|kb| kb / 1024)
.unwrap_or(0),
Err(_) => 0,
}
}
#[cfg(all(not(target_os = "linux"), unix))]
{
rss_mb() }
#[cfg(not(any(target_os = "linux", unix)))]
{
0
}
}
pub fn probe(label: &str) {
if enabled() {
eprintln!(
"[trace-rss] {label} RSS={} MB (peak {} MB)",
rss_mb(),
peak_mb()
);
}
}
#[cfg(all(target_os = "linux", target_env = "gnu"))]
unsafe extern "C" {
fn malloc_trim(pad: usize) -> i32;
}
pub fn trim() {
#[cfg(all(target_os = "linux", target_env = "gnu"))]
unsafe {
malloc_trim(0);
}
}
pub fn drop_vec<T>(v: Vec<T>) {
#[cfg(target_os = "linux")]
{
let ptr = v.as_ptr() as *mut libc::c_void;
let bytes = v.capacity() * std::mem::size_of::<T>();
drop(v);
if bytes >= 1 << 20 {
unsafe {
libc::madvise(ptr, bytes, 8 );
}
}
return;
}
#[allow(unreachable_code)]
drop(v);
}