veecle_osal_std/
thread.rs

1//! Thread-related abstractions.
2
3use std::cell::LazyCell;
4use std::num::NonZeroU64;
5use std::sync::atomic::{AtomicU64, Ordering};
6
7pub use veecle_osal_api::thread::ThreadAbstraction;
8
9/// Implements the [`ThreadAbstraction`] trait for standard Rust.
10#[derive(Debug)]
11pub struct Thread;
12
13/// Global counter for generating unique thread ids.
14static NEXT_THREAD_ID: AtomicU64 = AtomicU64::new(1);
15
16thread_local! {
17    /// Thread-local storage for the current thread's id.
18    static THREAD_ID: LazyCell<u64> = const { LazyCell::new(||{
19        // `Relaxed` is enough, we don't care about what specific value a thread sees.
20        // We just ensure that every value is unique.
21        // This assumes that creating 2^64 threads is impractical and no overflow occurs.
22        NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed)
23    }) };
24}
25
26impl ThreadAbstraction for Thread {
27    fn current_thread_id() -> NonZeroU64 {
28        NonZeroU64::new(THREAD_ID.with(|thread_id| **thread_id)).expect("overflow should not occur")
29    }
30}
31
32#[cfg(test)]
33#[cfg_attr(coverage_nightly, coverage(off))]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_thread_id_consistency() {
39        let id1 = Thread::current_thread_id();
40        let id2 = Thread::current_thread_id();
41        assert_eq!(
42            id1, id2,
43            "Thread id should be consistent within the same thread"
44        );
45    }
46
47    #[test]
48    fn test_thread_id_uniqueness() {
49        let main_id = Thread::current_thread_id();
50
51        let handle1 = std::thread::spawn(Thread::current_thread_id);
52        let handle2 = std::thread::spawn(Thread::current_thread_id);
53
54        let thread1_id = handle1.join().unwrap();
55        let thread2_id = handle2.join().unwrap();
56
57        assert_ne!(
58            main_id, thread1_id,
59            "Main thread and thread 1 should have different ids"
60        );
61        assert_ne!(
62            main_id, thread2_id,
63            "Main thread and thread 2 should have different ids"
64        );
65        assert_ne!(
66            thread1_id, thread2_id,
67            "Thread 1 and thread 2 should have different ids"
68        );
69    }
70}