1#[cfg(not(feature = "std"))]
2use spin::{Mutex as MutexImported, MutexGuard, Once as OnceImported, RwLock as RwLockImported};
3#[cfg(feature = "std")]
4use std::sync::{
5 Mutex as MutexImported, MutexGuard, OnceLock as OnceImported, RwLock as RwLockImported,
6};
7
8#[cfg(not(feature = "std"))]
9pub use spin::{Lazy, RwLockReadGuard, RwLockWriteGuard};
10#[cfg(feature = "std")]
11pub use std::sync::{LazyLock as Lazy, RwLockReadGuard, RwLockWriteGuard};
12
13#[cfg(target_has_atomic = "ptr")]
14pub use alloc::sync::Arc;
15#[cfg(not(target_has_atomic = "ptr"))]
16pub use portable_atomic_util::Arc;
17
18#[cfg(target_has_atomic = "ptr")]
19pub use core::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
20#[cfg(not(target_has_atomic = "ptr"))]
21pub use portable_atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
22
23#[derive(Debug, Default)]
30pub struct Mutex<T> {
31 inner: MutexImported<T>,
32}
33
34impl<T> Mutex<T> {
35 #[inline(always)]
37 pub const fn new(value: T) -> Self {
38 Self {
39 inner: MutexImported::new(value),
40 }
41 }
42
43 #[inline(always)]
45 pub fn lock(&self) -> Result<MutexGuard<'_, T>, alloc::string::String> {
46 #[cfg(not(feature = "std"))]
47 {
48 Ok(self.inner.lock())
49 }
50
51 #[cfg(feature = "std")]
52 {
53 use std::string::ToString;
54
55 self.inner.lock().map_err(|err| err.to_string())
56 }
57 }
58}
59
60#[derive(Debug)]
65pub struct RwLock<T> {
66 inner: RwLockImported<T>,
67}
68
69impl<T> RwLock<T> {
70 #[inline(always)]
72 pub const fn new(value: T) -> Self {
73 Self {
74 inner: RwLockImported::new(value),
75 }
76 }
77
78 #[inline(always)]
81 pub fn read(&self) -> Result<RwLockReadGuard<'_, T>, alloc::string::String> {
82 #[cfg(not(feature = "std"))]
83 {
84 Ok(self.inner.read())
85 }
86 #[cfg(feature = "std")]
87 {
88 use std::string::ToString;
89
90 self.inner.read().map_err(|err| err.to_string())
91 }
92 }
93
94 #[inline(always)]
97 pub fn write(&self) -> Result<RwLockWriteGuard<'_, T>, alloc::string::String> {
98 #[cfg(not(feature = "std"))]
99 {
100 Ok(self.inner.write())
101 }
102
103 #[cfg(feature = "std")]
104 {
105 use std::string::ToString;
106
107 self.inner.write().map_err(|err| err.to_string())
108 }
109 }
110}
111
112#[allow(dead_code)]
116#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
117pub struct ThreadId(core::num::NonZeroU64);
118
119pub struct SyncOnceCell<T>(OnceImported<T>);
123
124impl<T: core::fmt::Debug> Default for SyncOnceCell<T> {
125 fn default() -> Self {
126 Self::new()
127 }
128}
129
130impl<T: core::fmt::Debug> SyncOnceCell<T> {
131 #[inline(always)]
133 pub fn new() -> Self {
134 Self(OnceImported::new())
135 }
136
137 #[inline(always)]
139 pub fn initialized(value: T) -> Self {
140 #[cfg(not(feature = "std"))]
141 {
142 let cell = OnceImported::initialized(value);
143 Self(cell)
144 }
145
146 #[cfg(feature = "std")]
147 {
148 let cell = OnceImported::new();
149 cell.set(value).unwrap();
150
151 Self(cell)
152 }
153 }
154
155 #[inline(always)]
158 pub fn get_or_init<F>(&self, f: F) -> &T
159 where
160 F: FnOnce() -> T,
161 {
162 #[cfg(not(feature = "std"))]
163 {
164 self.0.call_once(f)
165 }
166
167 #[cfg(feature = "std")]
168 {
169 self.0.get_or_init(f)
170 }
171 }
172}