pub struct SyncUnsafeCell<T>(/* private fields */);Expand description
Thread-safe wrapper for UnsafeCell usable in static contexts.
SyncUnsafeCell<T> is a thin wrapper around UnsafeCell<T> that manually
implements the Sync and Send traits, allowing its use in static variables.
This is necessary in Rust 2024+ where static mut is no longer allowed.
§Safety
The manual implementation of Sync and Send is unsafe because the compiler
cannot verify that concurrent access is safe. It is the programmer’s responsibility
to ensure that:
-
In single-threaded environments (e.g., embedded bare-metal), there are no synchronization issues since only one thread of execution exists.
-
In multi-threaded environments, access to
SyncUnsafeCellmust be externally protected via mutexes, critical sections, or other synchronization primitives. -
No data race conditions occur during data access.
§Typical Usage
This structure is designed to replace static mut in embedded scenarios
where global mutability is necessary (e.g., hardware registers, shared buffers).
§Examples
use osal_rs::utils::SyncUnsafeCell;
// Global mutable variable in Rust 2024+
static COUNTER: SyncUnsafeCell<u32> = SyncUnsafeCell::new(0);
fn increment_counter() {
unsafe {
let counter = &mut *COUNTER.get();
*counter += 1;
}
}§Alternatives
For non-embedded code or when real synchronization is needed:
- Use
Mutex<T>orRwLock<T>for thread-safe protection - Use
AtomicUsize,AtomicBool, etc. for simple atomic types
Implementations§
Source§impl<T> SyncUnsafeCell<T>
impl<T> SyncUnsafeCell<T>
Sourcepub unsafe fn get(&self) -> *mut T
pub unsafe fn get(&self) -> *mut T
Gets a raw mutable pointer to the contained value.
§Safety
This function is unsafe because:
- It returns a raw pointer that bypasses the borrow checker
- The caller must ensure there are no mutable aliases
- Dereferencing the pointer without synchronization can cause data races
§Returns
A raw mutable pointer *mut T to the inner value.
§Examples
use osal_rs::utils::SyncUnsafeCell;
static VALUE: SyncUnsafeCell<i32> = SyncUnsafeCell::new(0);
unsafe {
let ptr = VALUE.get();
*ptr = 42;
}Trait Implementations§
impl<T> Send for SyncUnsafeCell<T>
Manual implementation of Send for SyncUnsafeCell<T>.
§Safety
This is unsafe because it asserts that SyncUnsafeCell<T> can be transferred
between threads. The inner type T may not be Send, so the caller must handle
memory safety.
impl<T> Sync for SyncUnsafeCell<T>
Manual implementation of Sync for SyncUnsafeCell<T>.
§Safety
This is unsafe because it asserts that SyncUnsafeCell<T> can be shared
between threads without causing data races. The caller must ensure synchronization.