use std::mem::{self, MaybeUninit};
use std::sync::{Mutex, MutexGuard};
use std::time::Instant;
use crate::id::{IdBorrow, IdStorage};
use crate::writer::Writer;
#[derive(Debug, Clone)]
pub enum BenchData {
Log { log: String, ts: f32, tid: usize },
Bench {
name: String,
ts: f32,
dur: f32,
tid: usize,
},
Count {
name: String,
ts: f32,
tid: usize,
data: Vec<(String, f32)>,
},
}
static mut GLOBAL_DATA: MaybeUninit<GlobalData> = MaybeUninit::uninit();
struct GlobalData {
pub program_begin: Instant,
pub queue_mutex: Mutex<Vec<BenchData>>,
pub id_storage: IdStorage,
}
pub fn begin() {
let program_begin = Instant::now();
let queue_mutex = Mutex::new(Vec::new());
let id_storage = IdStorage::new();
unsafe {
GLOBAL_DATA = MaybeUninit::new(GlobalData {
queue_mutex,
program_begin,
id_storage,
});
}
}
pub fn begin_time() -> Instant {
unsafe { (&*GLOBAL_DATA.as_ptr()).program_begin }
}
pub fn queue_mutex() -> MutexGuard<'static, Vec<BenchData>> {
unsafe { (&*GLOBAL_DATA.as_ptr()).queue_mutex.lock().unwrap() }
}
pub fn end(writers: Vec<Box<dyn Writer + 'static>>) {
let data = {
let mut lock = queue_mutex();
mem::replace(&mut *lock, Vec::new())
};
for writer in writers {
writer.end(&data);
}
unsafe {
let _gd = mem::replace(&mut GLOBAL_DATA, MaybeUninit::uninit()).assume_init();
}
}
thread_local! {
static TID: IdBorrow = unsafe { (&mut *GLOBAL_DATA.as_mut_ptr()).id_storage.gen() };
}
pub fn gen_id() {
TID.with(|_| {});
}
pub fn get_id() -> usize {
TID.with(|tid| tid.id())
}