]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | #![allow(dead_code)] // not used on all platforms |
2 | ||
3 | use crate::collections::BTreeMap; | |
4 | use crate::ptr; | |
5 | use crate::sync::atomic::{AtomicUsize, Ordering}; | |
60c5eb7d | 6 | use crate::sys_common::mutex::Mutex; |
e74abb32 XL |
7 | |
8 | pub type Key = usize; | |
9 | ||
60c5eb7d | 10 | type Dtor = unsafe extern "C" fn(*mut u8); |
e74abb32 XL |
11 | |
12 | static NEXT_KEY: AtomicUsize = AtomicUsize::new(0); | |
13 | ||
14 | static mut KEYS: *mut BTreeMap<Key, Option<Dtor>> = ptr::null_mut(); | |
60c5eb7d | 15 | static KEYS_LOCK: Mutex = Mutex::new(); |
e74abb32 XL |
16 | |
17 | #[thread_local] | |
18 | static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut(); | |
19 | ||
20 | unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> { | |
21 | if KEYS == ptr::null_mut() { | |
22 | KEYS = Box::into_raw(Box::new(BTreeMap::new())); | |
23 | } | |
24 | &mut *KEYS | |
25 | } | |
26 | ||
27 | unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> { | |
28 | if LOCALS == ptr::null_mut() { | |
29 | LOCALS = Box::into_raw(Box::new(BTreeMap::new())); | |
30 | } | |
31 | &mut *LOCALS | |
32 | } | |
33 | ||
34 | #[inline] | |
35 | pub unsafe fn create(dtor: Option<Dtor>) -> Key { | |
36 | let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst); | |
60c5eb7d | 37 | let _guard = KEYS_LOCK.lock(); |
e74abb32 XL |
38 | keys().insert(key, dtor); |
39 | key | |
40 | } | |
41 | ||
42 | #[inline] | |
43 | pub unsafe fn get(key: Key) -> *mut u8 { | |
60c5eb7d | 44 | if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() } |
e74abb32 XL |
45 | } |
46 | ||
47 | #[inline] | |
48 | pub unsafe fn set(key: Key, value: *mut u8) { | |
49 | locals().insert(key, value); | |
50 | } | |
51 | ||
52 | #[inline] | |
53 | pub unsafe fn destroy(key: Key) { | |
54 | keys().remove(&key); | |
55 | } | |
56 | ||
57 | #[inline] | |
58 | pub fn requires_synchronized_create() -> bool { | |
59 | false | |
60 | } |