1//! Synchronization utilities.
2
3#![cfg_attr(not(target_os = "macos"), allow(unused))]
4
5use std::{
6 ops::{Deref, DerefMut},
7 sync::atomic::*,
8};
9
10/// Makes the wrapped value [`Send`] + [`Sync`] even though it isn't.
11pub struct SyncWrap<T> {
12 pub value: T,
13}
14
15unsafe impl<T> Sync for SyncWrap<T> {}
16
17impl<T> Deref for SyncWrap<T> {
18 type Target = T;
19
20 #[inline]
21 fn deref(&self) -> &Self::Target {
22 &self.value
23 }
24}
25
26impl<T> DerefMut for SyncWrap<T> {
27 #[inline]
28 fn deref_mut(&mut self) -> &mut Self::Target {
29 &mut self.value
30 }
31}
32
33impl<T> SyncWrap<T> {
34 #[inline]
35 pub const unsafe fn new(value: T) -> Self {
36 Self { value }
37 }
38}
39
40/// A convenience wrapper around `AtomicBool`.
41pub(crate) struct AtomicFlag(AtomicBool);
42
43impl AtomicFlag {
44 #[inline]
45 pub const fn new(value: bool) -> Self {
46 Self(AtomicBool::new(value))
47 }
48
49 #[inline]
50 pub fn get(&self) -> bool {
51 self.0.load(order:Ordering::Relaxed)
52 }
53
54 #[inline]
55 pub fn set(&self, value: bool) {
56 self.0.store(val:value, order:Ordering::Relaxed);
57 }
58}
59
60/// Prevents false sharing by aligning to the cache line.
61#[derive(Clone, Copy)]
62#[repr(align(64))]
63pub(crate) struct CachePadded<T>(pub T);
64
65/// Alias to the atomic equivalent of `T`.
66pub(crate) type Atomic<T> = <T as WithAtomic>::Atomic;
67
68/// A type with an associated atomic type.
69pub(crate) trait WithAtomic {
70 type Atomic;
71}
72
73#[cfg(target_has_atomic = "ptr")]
74impl WithAtomic for usize {
75 type Atomic = AtomicUsize;
76}
77
78#[cfg(target_has_atomic = "ptr")]
79impl WithAtomic for isize {
80 type Atomic = AtomicIsize;
81}
82
83#[cfg(target_has_atomic = "8")]
84impl WithAtomic for u8 {
85 type Atomic = AtomicU8;
86}
87
88#[cfg(target_has_atomic = "8")]
89impl WithAtomic for i8 {
90 type Atomic = AtomicI8;
91}
92
93#[cfg(target_has_atomic = "16")]
94impl WithAtomic for u16 {
95 type Atomic = AtomicU16;
96}
97
98#[cfg(target_has_atomic = "16")]
99impl WithAtomic for i16 {
100 type Atomic = AtomicI16;
101}
102
103#[cfg(target_has_atomic = "32")]
104impl WithAtomic for u32 {
105 type Atomic = AtomicU32;
106}
107
108#[cfg(target_has_atomic = "32")]
109impl WithAtomic for i32 {
110 type Atomic = AtomicI32;
111}
112
113#[cfg(target_has_atomic = "64")]
114impl WithAtomic for u64 {
115 type Atomic = AtomicU64;
116}
117
118#[cfg(target_has_atomic = "64")]
119impl WithAtomic for i64 {
120 type Atomic = AtomicI64;
121}
122