state/type_map.rs
1use std::marker::PhantomData;
2use std::collections::HashMap;
3use std::hash::BuildHasherDefault;
4use std::any::{Any, TypeId};
5
6use crate::init::Init;
7use crate::ident_hash::IdentHash;
8use crate::shim::cell::UnsafeCell;
9use crate::shim::sync::atomic::{AtomicUsize, Ordering};
10use crate::shim::thread::yield_now;
11
12#[cfg(feature = "tls")]
13use crate::tls::LocalValue;
14
15/// A type map storing values based on types.
16///
17/// A type map stores at most _one_ instance of given type as well as _n_
18/// thread-local instances of a given type.
19///
20/// ## Type Bounds
21///
22/// A `TypeMap` can store values that are both `Send + Sync`, just `Send`, or
23/// neither. The [`TypeMap!`](macro.TypeMap.html) macro is used to specify the
24/// kind of type map:
25///
26/// ```rust
27/// use state::TypeMap;
28///
29/// // Values must implement `Send + Sync`. The type_map itself is `Send + Sync`.
30/// let type_map: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
31/// let type_map: TypeMap![Sync + Send] = <TypeMap![Sync + Send]>::new();
32///
33/// // Values must implement `Send`. The type_map itself is `Send`, `!Sync`.
34/// let type_map: TypeMap![Send] = <TypeMap![Send]>::new();
35///
36/// // Values needn't implement `Send` nor `Sync`. `TypeMap` is `!Send`, `!Sync`.
37/// let type_map: TypeMap![] = <TypeMap![]>::new();
38/// ```
39///
40/// ## Setting State
41///
42/// Global state is set via the [`set()`](TypeMap::set()) method and retrieved
43/// via the [`get()`](TypeMap::get()) method. The type of the value being set
44/// must meet the bounds of the `TypeMap`.
45///
46/// ```rust
47/// use state::TypeMap;
48///
49/// fn f_send_sync<T: Send + Sync + Clone + 'static>(value: T) {
50/// let type_map = <TypeMap![Send + Sync]>::new();
51/// type_map.set(value.clone());
52///
53/// let type_map = <TypeMap![Send]>::new();
54/// type_map.set(value.clone());
55///
56/// let type_map = <TypeMap![]>::new();
57/// type_map.set(value.clone());
58/// }
59///
60/// fn f_send<T: Send + Clone + 'static>(value: T) {
61/// // This would fail to compile since `T` may not be `Sync`.
62/// // let type_map = <TypeMap![Send + Sync]>::new();
63/// // type_map.set(value.clone());
64///
65/// let type_map = <TypeMap![Send]>::new();
66/// type_map.set(value.clone());
67///
68/// let type_map = <TypeMap![]>::new();
69/// type_map.set(value.clone());
70/// }
71///
72/// fn f<T: 'static>(value: T) {
73/// // This would fail to compile since `T` may not be `Sync` or `Send`.
74/// // let type_map = <TypeMap![Send + Sync]>::new();
75/// // type_map.set(value.clone());
76///
77/// // This would fail to compile since `T` may not be `Send`.
78/// // let type_map = <TypeMap![Send]>::new();
79/// // type_map.set(value.clone());
80///
81/// let type_map = <TypeMap![]>::new();
82/// type_map.set(value);
83/// }
84///
85/// // If `TypeMap` is `Send + Sync`, it can be `const`-constructed.
86/// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
87///
88/// TYPE_MAP.set(String::new());
89/// TYPE_MAP.get::<String>();
90/// ```
91///
92/// ## Freezing
93///
94/// By default, all `get`, `set`, `get_local`, and `set_local` calls result in
95/// synchronization overhead for safety. However, if calling `set` or
96/// `set_local` is no longer required, the overhead can be eliminated by
97/// _freezing_ the `TypeMap`. A frozen type map can only be read and never
98/// written to. Attempts to write to a frozen type map will be ignored.
99///
100/// To freeze a `TypeMap`, call [`freeze()`](TypeMap::freeze()). A frozen map
101/// can never be thawed. To check if a type map is frozen, call
102/// [`is_frozen()`](TypeMap::is_frozen()).
103///
104/// ## Thread-Local State
105///
106/// Thread-local state on a `Send + Sync` type map is set via the
107/// [`set_local()`](TypeMap::set_local()) method and retrieved via the
108/// [`get_local()`](TypeMap::get_local()) method. The type of the value being
109/// set must be transferable across thread boundaries but need not be
110/// thread-safe. In other words, it must satisfy `Send + 'static` but not
111/// necessarily `Sync`. Values retrieved from thread-local state are exactly
112/// that: local to the current thread. As such, you cannot use thread-local
113/// state to synchronize across multiple threads.
114///
115/// Thread-local state is initialized on an as-needed basis. The function used
116/// to initialize the thread-local state is passed in as an argument to
117/// `set_local`. When the state is retrieved from a given thread for the first
118/// time, the function is executed to generate the initial value. The function
119/// is executed at most once per thread. The same function is used for
120/// initialization across all threads.
121///
122/// **Note:** Rust reuses thread IDs across multiple threads. This means that is
123/// possible to set thread-local state in thread A, have that thread die, start
124/// a new thread B, and access the state set in tread A in thread B.
125///
126/// ### Example
127///
128/// Set and later retrieve a value of type T:
129///
130/// ```rust
131/// # struct T;
132/// # impl T { fn new() -> T { T } }
133/// # #[cfg(not(feature = "tls"))] fn test() { }
134/// # #[cfg(feature = "tls")] fn test() {
135/// use state::TypeMap;
136///
137/// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
138///
139/// TYPE_MAP.set_local(|| T::new());
140/// TYPE_MAP.get_local::<T>();
141/// # }
142/// # fn main() { test() }
143/// ```
144pub struct TypeMap<K: kind::Kind> {
145 init: Init,
146 map: UnsafeCell<Option<TypeIdMap>>,
147 mutex: AtomicUsize,
148 frozen: bool,
149 /// Force !Send (and carry the type).
150 _kind: PhantomData<*mut K>
151}
152
153mod kind {
154 pub trait Kind { }
155
156 pub struct Send;
157 impl Kind for Send {}
158
159 pub struct SendSync;
160 impl Kind for SendSync {}
161
162 pub struct Neither;
163 impl Kind for Neither {}
164}
165
166pub type TypeMapSend = TypeMap<kind::Send>;
167pub type TypeMapSendSync = TypeMap<kind::SendSync>;
168pub type TypeMapNeither = TypeMap<kind::Neither>;
169
170/// Type constructor for [`TypeMap`](struct@TypeMap) variants.
171#[macro_export]
172macro_rules! TypeMap {
173 () => ($crate::type_map::TypeMapNeither);
174 (Send) => ($crate::type_map::TypeMapSend);
175 (Send + Sync) => ($crate::type_map::TypeMapSendSync);
176 (Sync + Send) => ($crate::type_map::TypeMapSendSync);
177}
178
179macro_rules! new {
180 () => (
181 TypeMap {
182 init: Init::new(),
183 map: UnsafeCell::new(None),
184 mutex: AtomicUsize::new(0),
185 frozen: false,
186 _kind: PhantomData,
187 }
188 )
189}
190
191type TypeIdMap = HashMap<TypeId, Box<dyn Any>, BuildHasherDefault<IdentHash>>;
192
193impl TypeMap<kind::SendSync> {
194 /// Creates a new type map with no stored values.
195 ///
196 /// ## Example
197 ///
198 /// Create a globally available type map:
199 ///
200 /// ```rust
201 /// use state::TypeMap;
202 ///
203 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
204 /// ```
205 #[cfg(not(loom))]
206 pub const fn new() -> Self {
207 new!()
208 }
209
210 #[cfg(loom)]
211 pub fn new() -> Self {
212 new!()
213 }
214
215 /// Sets the global state for type `T` if it has not been set before and
216 /// `self` is not frozen.
217 ///
218 /// If the state for `T` has previously been set or `self` is frozen, the
219 /// state is unchanged and `false` is returned. Otherwise `true` is
220 /// returned.
221 ///
222 /// # Example
223 ///
224 /// Set the state for `AtomicUsize`. The first `set` is succesful while the
225 /// second fails.
226 ///
227 /// ```rust
228 /// # use std::sync::atomic::AtomicUsize;
229 /// use state::TypeMap;
230 ///
231 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
232 ///
233 /// assert_eq!(TYPE_MAP.set(AtomicUsize::new(0)), true);
234 /// assert_eq!(TYPE_MAP.set(AtomicUsize::new(1)), false);
235 /// ```
236 #[inline]
237 pub fn set<T: Send + Sync + 'static>(&self, state: T) -> bool {
238 unsafe { self._set(state) }
239 }
240
241 /// Sets the thread-local state for type `T` if it has not been set before.
242 ///
243 /// The state for type `T` will be initialized via the `state_init` function as
244 /// needed. If the state for `T` has previously been set, the state is unchanged
245 /// and `false` is returned. Returns `true` if the thread-local state is
246 /// successfully set to be initialized with `state_init`.
247 ///
248 /// # Example
249 ///
250 /// ```rust
251 /// # use std::cell::Cell;
252 /// use state::TypeMap;
253 ///
254 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
255 ///
256 /// struct MyState(Cell<usize>);
257 ///
258 /// assert_eq!(TYPE_MAP.set_local(|| MyState(Cell::new(1))), true);
259 /// assert_eq!(TYPE_MAP.set_local(|| MyState(Cell::new(2))), false);
260 /// ```
261 #[inline]
262 #[cfg(feature = "tls")]
263 pub fn set_local<T, F>(&self, state_init: F) -> bool
264 where T: Send + 'static, F: Fn() -> T + Send + Sync + 'static
265 {
266 self.set::<LocalValue<T>>(LocalValue::new(state_init))
267 }
268
269 /// Attempts to retrieve the thread-local state for type `T`.
270 ///
271 /// Returns `Some` if the state has previously been set via
272 /// [set_local](#method.set_local). Otherwise returns `None`.
273 ///
274 /// # Example
275 ///
276 /// ```rust
277 /// # use std::cell::Cell;
278 /// use state::TypeMap;
279 ///
280 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
281 ///
282 /// struct MyState(Cell<usize>);
283 ///
284 /// TYPE_MAP.set_local(|| MyState(Cell::new(10)));
285 ///
286 /// let my_state = TYPE_MAP.try_get_local::<MyState>().expect("MyState");
287 /// assert_eq!(my_state.0.get(), 10);
288 /// ```
289 #[inline]
290 #[cfg(feature = "tls")]
291 pub fn try_get_local<T: Send + 'static>(&self) -> Option<&T> {
292 // TODO: This will take a lock on the HashMap unnecessarily. Ideally
293 // we'd have a `HashMap` per thread mapping from TypeId to (T, F).
294 self.try_get::<LocalValue<T>>().map(|value| value.get())
295 }
296
297 /// Retrieves the thread-local state for type `T`.
298 ///
299 /// # Panics
300 ///
301 /// Panics if the thread-local state for type `T` has not previously been set
302 /// via [set_local](#method.set_local). Use
303 /// [try_get_local](#method.try_get_local) for a non-panicking version.
304 ///
305 /// # Example
306 ///
307 /// ```rust
308 /// # use std::cell::Cell;
309 /// use state::TypeMap;
310 ///
311 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
312 ///
313 /// struct MyState(Cell<usize>);
314 ///
315 /// TYPE_MAP.set_local(|| MyState(Cell::new(10)));
316 ///
317 /// let my_state = TYPE_MAP.get_local::<MyState>();
318 /// assert_eq!(my_state.0.get(), 10);
319 /// ```
320 #[inline]
321 #[cfg(feature = "tls")]
322 pub fn get_local<T: Send + 'static>(&self) -> &T {
323 self.try_get_local::<T>()
324 .expect("type_map::get_local(): get_local() called before set_local()")
325 }
326}
327
328unsafe impl Send for TypeMap<kind::SendSync> { }
329unsafe impl Sync for TypeMap<kind::SendSync> { }
330
331#[cfg(test)] static_assertions::assert_impl_all!(TypeMap![Send + Sync]: Send, Sync);
332#[cfg(test)] static_assertions::assert_impl_all!(TypeMap![Sync + Send]: Send, Sync);
333
334impl TypeMap<kind::Send> {
335 /// Creates a new type map with no stored values.
336 ///
337 /// # Example
338 ///
339 /// ```rust
340 /// use std::cell::Cell;
341 ///
342 /// use state::TypeMap;
343 ///
344 /// let type_map = <TypeMap![Send]>::new();
345 ///
346 /// let value: Cell<u8> = Cell::new(10);
347 /// type_map.set(value);
348 /// assert_eq!(type_map.get::<Cell<u8>>().get(), 10);
349 ///
350 /// type_map.get::<Cell<u8>>().set(99);
351 /// assert_eq!(type_map.get::<Cell<u8>>().get(), 99);
352 /// ```
353 pub fn new() -> Self {
354 // SAFETY: this can't be `const` or we violate `Sync`.
355 new!()
356 }
357
358 /// Sets the global state for type `T` if it has not been set before and
359 /// `self` is not frozen.
360 ///
361 /// If the state for `T` has previously been set or `self` is frozen, the
362 /// state is unchanged and `false` is returned. Otherwise `true` is
363 /// returned.
364 ///
365 /// # Example
366 ///
367 /// Set the state. The first `set` is succesful while the second fails.
368 ///
369 /// ```rust
370 /// # use std::sync::atomic::AtomicUsize;
371 /// use state::TypeMap;
372 ///
373 /// let type_map = <TypeMap![Send]>::new();
374 /// assert!(type_map.set(AtomicUsize::new(0)));
375 /// assert!(!type_map.set(AtomicUsize::new(1)));
376 /// ```
377 #[inline]
378 pub fn set<T: Send + 'static>(&self, state: T) -> bool {
379 unsafe { self._set(state) }
380 }
381}
382
383unsafe impl Send for TypeMap<kind::Send> { }
384
385#[cfg(test)] static_assertions::assert_impl_all!(TypeMap![Send]: Send);
386#[cfg(test)] static_assertions::assert_not_impl_any!(TypeMap![Send]: Sync);
387#[cfg(test)] static_assertions::assert_not_impl_any!(TypeMap<kind::Send>: Sync);
388
389impl TypeMap<kind::Neither> {
390 /// Creates a new type_map with no stored values.
391 ///
392 /// # Example
393 ///
394 /// ```rust
395 /// use std::cell::Cell;
396 /// use state::TypeMap;
397 ///
398 /// let type_map = <TypeMap![]>::new();
399 ///
400 /// let value: Cell<u8> = Cell::new(10);
401 /// type_map.set(value);
402 /// assert_eq!(type_map.get::<Cell<u8>>().get(), 10);
403 ///
404 /// type_map.get::<Cell<u8>>().set(99);
405 /// assert_eq!(type_map.get::<Cell<u8>>().get(), 99);
406 /// ```
407 pub fn new() -> Self {
408 // SAFETY: this can't be `const` or we violate `Sync`.
409 new!()
410 }
411
412 /// Sets the global state for type `T` if it has not been set before and
413 /// `self` is not frozen.
414 ///
415 /// If the state for `T` has previously been set or `self` is frozen, the
416 /// state is unchanged and `false` is returned. Otherwise `true` is
417 /// returned.
418 ///
419 /// # Example
420 ///
421 /// Set the state. The first `set` is succesful while the second fails.
422 ///
423 /// ```rust
424 /// use std::cell::Cell;
425 /// use state::TypeMap;
426 ///
427 /// let type_map = <TypeMap![]>::new();
428 /// assert!(type_map.set(Cell::new(10)));
429 /// assert!(!type_map.set(Cell::new(17)));
430 /// ```
431 #[inline]
432 pub fn set<T: 'static>(&self, state: T) -> bool {
433 unsafe { self._set(state) }
434 }
435}
436
437#[cfg(test)] static_assertions::assert_not_impl_any!(TypeMap![]: Send, Sync);
438#[cfg(test)] static_assertions::assert_not_impl_any!(TypeMap<kind::Neither>: Send, Sync);
439
440impl<K: kind::Kind> TypeMap<K> {
441 // Initializes the `map` if needed.
442 unsafe fn init_map_if_needed(&self) {
443 if self.init.needed() {
444 self.map.with_mut(|ptr| *ptr = Some(HashMap::<_, _, _>::default()));
445 self.init.mark_complete();
446 }
447 }
448
449 // Initializes the `map` if needed and returns a mutable ref to it.
450 //
451 // SAFETY: Caller must ensure mutual exclusion of calls to this function
452 // and/or calls to `map_ref`.
453 #[inline(always)]
454 #[allow(clippy::mut_from_ref)]
455 unsafe fn map_mut(&self) -> &mut TypeIdMap {
456 self.init_map_if_needed();
457 self.map.with_mut(|ptr| (*ptr).as_mut().unwrap())
458 }
459
460 // Initializes the `map` if needed and returns an immutable ref to it.
461 //
462 // SAFETY: Caller must ensure mutual exclusion of calls to this function
463 // and/or calls to `map_mut`.
464 #[inline(always)]
465 unsafe fn map_ref(&self) -> &TypeIdMap {
466 self.init_map_if_needed();
467 self.map.with(|ptr| (*ptr).as_ref().unwrap())
468 }
469
470 /// SAFETY: The caller needs to ensure that `T` has the required bounds
471 /// `Sync` or `Send` bounds.
472 unsafe fn _set<T: 'static>(&self, state: T) -> bool {
473 if self.is_frozen() {
474 return false;
475 }
476
477 self.lock();
478 let map = self.map_mut();
479 let type_id = TypeId::of::<T>();
480 let already_set = map.contains_key(&type_id);
481 if !already_set {
482 map.insert(type_id, Box::new(state) as Box<dyn Any>);
483 }
484
485 self.unlock();
486 !already_set
487 }
488
489 /// SAFETY: The caller needs to ensure that the `T` returned from the `f` is
490 /// not dependent on the stability of memory slots in the map. It also needs
491 /// to ensure that `f` does not panic if liveness is desired.
492 unsafe fn with_map_ref<'a, F, T: 'a>(&'a self, f: F) -> T
493 where F: FnOnce(&'a TypeIdMap) -> T
494 {
495 // If we're frozen, there can't be any concurrent writers, so we're
496 // free to read this safely without taking a lock.
497 if self.is_frozen() {
498 f(self.map_ref())
499 } else {
500 self.lock();
501 let result = f(self.map_ref());
502 self.unlock();
503 result
504 }
505 }
506
507 /// Attempts to retrieve the global state for type `T`.
508 ///
509 /// Returns `Some` if the state has previously been [set](#method.set).
510 /// Otherwise returns `None`.
511 ///
512 /// # Example
513 ///
514 /// ```rust
515 /// # use std::sync::atomic::{AtomicUsize, Ordering};
516 /// use state::TypeMap;
517 ///
518 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
519 ///
520 /// struct MyState(AtomicUsize);
521 ///
522 /// // State for `T` is initially unset.
523 /// assert!(TYPE_MAP.try_get::<MyState>().is_none());
524 ///
525 /// TYPE_MAP.set(MyState(AtomicUsize::new(0)));
526 ///
527 /// let my_state = TYPE_MAP.try_get::<MyState>().expect("MyState");
528 /// assert_eq!(my_state.0.load(Ordering::Relaxed), 0);
529 /// ```
530 #[inline]
531 pub fn try_get<T: 'static>(&self) -> Option<&T> {
532 // SAFETY: `deanonymization` takes a potentially unstable refrence to an
533 // `AnyObject` and converts it into a stable address: it is converting
534 // an `&Box<dyn Any>` into the inner `&T`. The inner item is never
535 // dropped until `self` is dropped: it is never replaced.
536 unsafe {
537 self.with_map_ref(|map| {
538 map.get(&TypeId::of::<T>()).and_then(|ptr| ptr.downcast_ref())
539 })
540 }
541 }
542
543 /// Retrieves the global state for type `T`.
544 ///
545 /// # Panics
546 ///
547 /// Panics if the state for type `T` has not previously been
548 /// [`set()`](Self::set()). Use [`try_get()`](Self::try_get()) for a
549 /// non-panicking version.
550 ///
551 /// # Example
552 ///
553 /// ```rust
554 /// # use std::sync::atomic::{AtomicUsize, Ordering};
555 /// use state::TypeMap;
556 ///
557 /// static TYPE_MAP: TypeMap![Send + Sync] = <TypeMap![Send + Sync]>::new();
558 ///
559 /// struct MyState(AtomicUsize);
560 ///
561 /// TYPE_MAP.set(MyState(AtomicUsize::new(0)));
562 ///
563 /// let my_state = TYPE_MAP.get::<MyState>();
564 /// assert_eq!(my_state.0.load(Ordering::Relaxed), 0);
565 /// ```
566 #[inline]
567 pub fn get<T: 'static>(&self) -> &T {
568 self.try_get()
569 .expect("type_map::get(): get() called before set() for given type")
570 }
571
572 /// Freezes the type_map. A frozen type_map disallows writes allowing for
573 /// synchronization-free reads.
574 ///
575 /// # Example
576 ///
577 /// ```rust
578 /// use state::TypeMap;
579 ///
580 /// // A new type_map starts unfrozen and can be written to.
581 /// let mut type_map = <TypeMap![Send + Sync]>::new();
582 /// assert_eq!(type_map.set(1usize), true);
583 ///
584 /// // While unfrozen, `get`s require synchronization.
585 /// assert_eq!(type_map.get::<usize>(), &1);
586 ///
587 /// // After freezing, calls to `set` or `set_local `will fail.
588 /// type_map.freeze();
589 /// assert_eq!(type_map.set(1u8), false);
590 /// assert_eq!(type_map.set("hello"), false);
591 ///
592 /// // Calls to `get` or `get_local` are synchronization-free when frozen.
593 /// assert_eq!(type_map.try_get::<u8>(), None);
594 /// assert_eq!(type_map.get::<usize>(), &1);
595 /// ```
596 #[inline(always)]
597 pub fn freeze(&mut self) {
598 self.frozen = true;
599 }
600
601 /// Returns `true` if the type_map is frozen and `false` otherwise.
602 ///
603 /// # Example
604 ///
605 /// ```rust
606 /// use state::TypeMap;
607 ///
608 /// // A new type_map starts unfrozen and is frozen using `freeze`.
609 /// let mut type_map = <TypeMap![Send]>::new();
610 /// assert_eq!(type_map.is_frozen(), false);
611 ///
612 /// type_map.freeze();
613 /// assert_eq!(type_map.is_frozen(), true);
614 /// ```
615 #[inline(always)]
616 pub fn is_frozen(&self) -> bool {
617 self.frozen
618 }
619
620 /// Returns the number of distinctly typed values in `self`.
621 ///
622 /// # Example
623 ///
624 /// ```rust
625 /// use state::TypeMap;
626 ///
627 /// let type_map = <TypeMap![Send + Sync]>::new();
628 /// assert_eq!(type_map.len(), 0);
629 ///
630 /// assert_eq!(type_map.set(1usize), true);
631 /// assert_eq!(type_map.len(), 1);
632 ///
633 /// assert_eq!(type_map.set(2usize), false);
634 /// assert_eq!(type_map.len(), 1);
635 ///
636 /// assert_eq!(type_map.set(1u8), true);
637 /// assert_eq!(type_map.len(), 2);
638 /// ```
639 #[inline]
640 pub fn len(&self) -> usize {
641 // SAFETY: We retrieve a `usize`, which is clearly stable.
642 unsafe { self.with_map_ref(|map| map.len()) }
643 }
644
645 /// Returns `true` if `self` contains zero values.
646 ///
647 /// # Example
648 ///
649 /// ```rust
650 /// use state::TypeMap;
651 ///
652 /// let type_map = <TypeMap![Send + Sync]>::new();
653 /// assert!(type_map.is_empty());
654 ///
655 /// assert_eq!(type_map.set(1usize), true);
656 /// assert!(!type_map.is_empty());
657 /// ```
658 #[inline]
659 pub fn is_empty(&self) -> bool {
660 self.len() == 0
661 }
662
663 #[inline(always)]
664 fn lock(&self) {
665 while self.mutex.compare_exchange(0, 1, Ordering::AcqRel, Ordering::Relaxed).is_err() {
666 yield_now();
667 }
668 }
669
670 #[inline(always)]
671 fn unlock(&self) {
672 assert!(self.mutex.compare_exchange(1, 0, Ordering::AcqRel, Ordering::Relaxed).is_ok());
673 }
674}
675
676impl Default for TypeMap![Send + Sync] {
677 fn default() -> Self {
678 <TypeMap![Send + Sync]>::new()
679 }
680}
681
682impl Default for TypeMap![Send] {
683 fn default() -> Self {
684 <TypeMap![Send]>::new()
685 }
686}
687
688impl Default for TypeMap![] {
689 fn default() -> Self {
690 <TypeMap![]>::new()
691 }
692}
693
694impl<K: kind::Kind> std::fmt::Debug for TypeMap<K> {
695 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
696 f.debug_struct("TypeMap")
697 .field("len", &self.len())
698 .finish()
699 }
700}