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}