zephyr/simpletls.rs
1//! A simple TLS helping tool.
2//!
3//! Until this crate implements general TLS support, similar to std, this simpletls module can
4//! provide a simplified type of thread-local storage.
5
6extern crate alloc;
7
8use alloc::vec::Vec;
9use zephyr_sys::{k_current_get, k_thread};
10
11/// A container for simple thread local storage.
12///
13/// This will maintain a mapping between Zephyr threads and a value of type T. Entries will have to
14/// be added manually, generally when each thread is started.
15///
16/// Note that T must implement Copy, as it is not safe to retain references to the inner data
17/// outside of this api.
18///
19/// T must also implement Send, since although 'get' always retrieves the current thread's data,
20/// `insert` will typically need to move `T` across threads.
21pub struct SimpleTls<T: Copy + Send> {
22 map: Vec<(usize, T)>,
23}
24
25impl<T: Copy + Send> SimpleTls<T> {
26 /// Create a new SimpleTls.
27 pub const fn new() -> Self {
28 Self { map: Vec::new() }
29 }
30
31 /// Insert a new association into the SimpleTls.
32 ///
33 /// If this thread has already been added, the value will be replaced.
34 pub fn insert(&mut self, thread: *const k_thread, data: T) {
35 let thread = thread as usize;
36
37 match self.map.binary_search_by(|(id, _)| id.cmp(&thread)) {
38 Ok(pos) => self.map[pos] = (thread, data), // Replace existing.
39 Err(pos) => self.map.insert(pos, (thread, data)),
40 }
41 }
42
43 /// Lookup the data associated with a given thread.
44 pub fn get(&self) -> Option<T> {
45 let thread = unsafe { k_current_get() } as usize;
46
47 self.map
48 .binary_search_by(|(id, _)| id.cmp(&thread))
49 .ok()
50 .map(|pos| self.map[pos].1)
51 }
52}