moto_rt/
tls.rs

1use core::sync::atomic::Ordering;
2
3use crate::RtVdsoVtable;
4
5pub type Key = usize;
6
7#[inline]
8pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {
9    let vdso_create: extern "C" fn(u64) -> Key = unsafe {
10        core::mem::transmute(
11            RtVdsoVtable::get().tls_create.load(Ordering::Relaxed) as usize as *const (),
12        )
13    };
14
15    vdso_create(match dtor {
16        Some(func) => func as *const () as usize as u64,
17        None => 0,
18    })
19}
20
21/// # Safety
22///
23/// It is kinda safe, but stdlib wraps it in 'unsafe' and fails to compile if we dont' mark it safe.
24#[inline]
25pub unsafe fn set(key: Key, value: *mut u8) {
26    let vdso_set: extern "C" fn(Key, *mut u8) = unsafe {
27        core::mem::transmute(
28            RtVdsoVtable::get().tls_set.load(Ordering::Relaxed) as usize as *const ()
29        )
30    };
31
32    vdso_set(key, value)
33}
34
35/// # Safety
36///
37/// It is kinda safe, but stdlib wraps it in 'unsafe' and fails to compile if we dont' mark it safe.
38#[inline]
39pub unsafe fn get(key: Key) -> *mut u8 {
40    let vdso_get: extern "C" fn(Key) -> *mut u8 = unsafe {
41        core::mem::transmute(
42            RtVdsoVtable::get().tls_get.load(Ordering::Relaxed) as usize as *const ()
43        )
44    };
45
46    vdso_get(key)
47}
48
49/// # Safety
50///
51/// It is kinda safe, but stdlib wraps it in 'unsafe' and fails to compile if we dont' mark it safe.
52#[inline]
53pub unsafe fn destroy(key: Key) {
54    let vdso_destroy: extern "C" fn(Key) = unsafe {
55        core::mem::transmute(
56            RtVdsoVtable::get().tls_destroy.load(Ordering::Relaxed) as usize as *const (),
57        )
58    };
59
60    vdso_destroy(key)
61}