dualcache_ff/tls/
std_tls.rs1use super::TlsProvider;
2use crate::sync::atomic::{AtomicUsize, Ordering};
3use crate::sync::index_types::TickType;
4use core::cell::{Cell, RefCell};
5use std::sync::Mutex;
6use alloc::vec::Vec;
7
8struct IdAllocator {
9 free_list: Mutex<Vec<usize>>,
10 next_id: AtomicUsize,
11}
12
13static ALLOCATOR: IdAllocator = IdAllocator {
14 free_list: Mutex::new(Vec::new()),
15 next_id: AtomicUsize::new(0),
16};
17
18struct ThreadIdGuard {
19 id: usize,
20}
21
22impl Drop for ThreadIdGuard {
23 fn drop(&mut self) {
24 if let Ok(mut list) = ALLOCATOR.free_list.lock() {
25 list.push(self.id);
26 }
27 }
28}
29
30thread_local! {
31 static WORKER_ID: usize = {
32 let id = if let Ok(mut list) = ALLOCATOR.free_list.lock() {
33 list.pop().unwrap_or_else(|| ALLOCATOR.next_id.fetch_add(1, Ordering::Relaxed))
34 } else {
35 ALLOCATOR.next_id.fetch_add(1, Ordering::Relaxed)
36 };
37
38 GUARD.with(|g| {
39 *g.borrow_mut() = Some(ThreadIdGuard { id });
40 });
41 id
42 };
43
44 static GUARD: RefCell<Option<ThreadIdGuard>> = const { RefCell::new(None) };
45
46 static HIT_BUF: RefCell<([usize; 64], usize)> = const { RefCell::new(([0; 64], 0)) };
49
50 static L1_FILTER: RefCell<([u8; 4096], usize)> = const { RefCell::new(([0; 4096], 0)) };
53
54 static LAST_FLUSH_TICK: Cell<TickType> = const { Cell::new(0) };
58
59 static WARMUP_STATE: Cell<u8> = const { Cell::new(0) };
61}
62
63#[derive(Clone)]
64pub struct DefaultTls;
65
66impl TlsProvider for DefaultTls {
67 #[inline(always)]
68 fn get_worker_id(&self) -> Option<usize> {
69 Some(WORKER_ID.with(|id| *id))
70 }
71
72 #[inline(always)]
73 fn with_hit_buf(&self, f: &mut dyn FnMut(&mut ([usize; 64], usize))) {
74 HIT_BUF.with(|buf| {
75 f(&mut *buf.borrow_mut());
76 });
77 }
78
79 #[inline(always)]
80 fn with_l1_filter(&self, f: &mut dyn FnMut(&mut ([u8; 4096], usize))) {
81 L1_FILTER.with(|filter| {
82 f(&mut *filter.borrow_mut());
83 });
84 }
85
86 #[inline(always)]
87 fn with_last_flush_tick(&self, f: &mut dyn FnMut(&mut TickType)) {
88 LAST_FLUSH_TICK.with(|cell| {
89 let mut val = cell.get();
90 f(&mut val);
91 cell.set(val);
92 });
93 }
94
95 #[inline(always)]
96 fn with_warmup_state(&self, f: &mut dyn FnMut(&mut u8)) {
97 WARMUP_STATE.with(|cell| {
98 let mut val = cell.get();
99 f(&mut val);
100 cell.set(val);
101 });
102 }
103}