cordyceps/
util.rs
1use core::fmt;
2
3#[cfg(target_has_atomic = "ptr")]
4pub(crate) use has_cas_atomics::*;
5
6#[cfg(target_has_atomic = "ptr")]
7mod has_cas_atomics {
8 use core::{
9 fmt,
10 ops::{Deref, DerefMut},
11 };
12
13 #[derive(Debug, Clone)]
15 pub(crate) struct Backoff {
16 exp: u8,
17 max: u8,
18 }
19
20 pub(crate) use cache_pad::CachePadded;
21
22 #[cfg(feature = "no-cache-pad")]
26 mod cache_pad {
27 #[derive(Clone, Copy, Default, Hash, PartialEq, Eq)]
28 pub(crate) struct CachePadded<T>(pub(crate) T);
29 }
30
31 #[cfg(not(feature = "no-cache-pad"))]
34 mod cache_pad {
35 #[cfg_attr(any(target_arch = "x86_64", target_arch = "aarch64"), repr(align(128)))]
36 #[cfg_attr(
37 not(any(target_arch = "x86_64", target_arch = "aarch64")),
38 repr(align(64))
39 )]
40 #[derive(Clone, Copy, Default, Hash, PartialEq, Eq)]
41 pub(crate) struct CachePadded<T>(pub(crate) T);
42 }
43
44 impl Backoff {
47 pub(crate) const DEFAULT_MAX_EXPONENT: u8 = 8;
48
49 pub(crate) const fn new() -> Self {
50 Self {
51 exp: 0,
52 max: Self::DEFAULT_MAX_EXPONENT,
53 }
54 }
55
56 #[allow(dead_code)]
58 pub(crate) fn with_max_exponent(max: u8) -> Self {
59 assert!(max <= Self::DEFAULT_MAX_EXPONENT);
60 Self { exp: 0, max }
61 }
62
63 #[inline(always)]
65 pub(crate) fn spin(&mut self) {
66 use crate::loom::hint;
67
68 for _ in 0..(1 << self.exp) {
70 hint::spin_loop();
71 }
72
73 if self.exp < self.max {
74 self.exp += 1
75 }
76 }
77 }
78
79 impl Default for Backoff {
80 fn default() -> Self {
81 Self::new()
82 }
83 }
84
85 impl<T> Deref for CachePadded<T> {
88 type Target = T;
89
90 #[inline]
91 fn deref(&self) -> &T {
92 &self.0
93 }
94 }
95
96 impl<T> DerefMut for CachePadded<T> {
97 #[inline]
98 fn deref_mut(&mut self) -> &mut T {
99 &mut self.0
100 }
101 }
102
103 impl<T: fmt::Debug> fmt::Debug for CachePadded<T> {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 self.0.fmt(f)
106 }
107 }
108}
109
110macro_rules! test_trace {
111 ($($tt:tt)*) => {
112 #[cfg(test)]
113 tracing::trace!($($tt)*)
114 }
115}
116
117pub(crate) struct FmtOption<'a, T> {
118 opt: Option<&'a T>,
119 or_else: &'a str,
120}
121
122impl<'a, T> FmtOption<'a, T> {
125 pub(crate) fn new(opt: &'a Option<T>) -> Self {
126 Self {
127 opt: opt.as_ref(),
128 or_else: "None",
129 }
130 }
131}
132
133impl<T: fmt::Debug> fmt::Debug for FmtOption<'_, T> {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 match self.opt {
136 Some(val) => val.fmt(f),
137 None => f.write_str(self.or_else),
138 }
139 }
140}
141
142impl<T: fmt::Display> fmt::Display for FmtOption<'_, T> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 match self.opt {
145 Some(val) => val.fmt(f),
146 None => f.write_str(self.or_else),
147 }
148 }
149}
150
151#[cfg(test)]
152pub(crate) fn assert_send_sync<T: Send + Sync>() {}