tikv_jemalloc_ctl/
macros.rs

1//! Utility macros
2
3macro_rules! types {
4    ($id:ident[ str: $byte_string:expr, $mib:ty, $name_to_mib:ident ]  |
5     docs: $(#[$doc:meta])*
6     mib_docs: $(#[$doc_mib:meta])*
7    ) => {
8        paste::paste! {
9            $(#[$doc])*
10            #[allow(non_camel_case_types)]
11            pub struct $id;
12
13            impl $id {
14                const NAME: &'static crate::keys::Name = {
15                    union U<'a> {
16                        bytes: &'a [u8],
17                        name: &'a crate::keys::Name
18                    }
19
20                    unsafe { U { bytes: $byte_string }.name }
21                };
22                /// Returns Management Information Base (MIB)
23                ///
24                /// This value can be used to access the key without doing string lookup.
25                pub fn mib() -> crate::error::Result<[<$id _mib>]> {
26                    Ok([<$id _mib>](Self::NAME.$name_to_mib()?))
27                }
28
29                /// Key [`crate::keys::Name`].
30                pub fn name() -> &'static crate::keys::Name {
31                    Self::NAME
32                }
33            }
34
35            $(#[$doc_mib])*
36            #[repr(transparent)]
37            #[derive(Copy, Clone)]
38            #[allow(non_camel_case_types)]
39            pub struct [<$id _mib>](pub crate::keys::$mib);
40        }
41    };
42}
43
44/// Read
45macro_rules! r {
46    ($id:ident => $ret_ty:ty) => {
47        paste::paste! {
48            impl $id {
49                /// Reads value using string API.
50                pub fn read() -> crate::error::Result<$ret_ty> {
51                    use crate::keys::Access;
52                    Self::NAME.read()
53                }
54            }
55
56            impl [<$id _mib>] {
57                /// Reads value using MIB API.
58                pub fn read(self) -> crate::error::Result<$ret_ty> {
59                    use crate::keys::Access;
60                    self.0.read()
61                }
62            }
63
64            #[cfg(test)]
65            #[test]
66            #[cfg(not(target_arch = "mips64el"))]
67            #[allow(unused)]
68            fn [<$id _read_test>]() {
69                match stringify!($id) {
70                    "background_thread" |
71                    "max_background_threads"
72                    if cfg!(target_os = "macos") => return,
73                    _ => (),
74                }
75
76                let a = $id::read().unwrap();
77
78                let mib = $id::mib().unwrap();
79                let b = mib.read().unwrap();
80
81                #[cfg(feature = "use_std")]
82                println!(
83                    concat!(
84                        stringify!($id),
85                        " (read): \"{}\" - \"{}\""),
86                    a, b
87                );
88            }
89        }
90    };
91}
92
93/// Write
94macro_rules! w {
95    ($id:ident => $ret_ty:ty) => {
96        paste::paste! {
97            impl $id {
98                /// Writes `value` using string API.
99                pub fn write(value: $ret_ty) -> crate::error::Result<()> {
100                    use crate::keys::Access;
101                    Self::NAME.write(value)
102                }
103            }
104
105            impl [<$id _mib>] {
106                /// Writes `value` using MIB API.
107                pub fn write(self, value: $ret_ty) -> crate::error::Result<()> {
108                    use crate::keys::Access;
109                    self.0.write(value)
110                }
111            }
112
113            #[cfg(test)]
114            #[test]
115            #[cfg(not(target_arch = "mips64el"))]
116            fn [<$id _write_test>]() {
117                match stringify!($id) {
118                    "background_thread" |
119                    "max_background_threads"
120                        if cfg!(target_os = "macos") => return,
121                    _ => (),
122                }
123
124                let _ = $id::write($ret_ty::default()).unwrap();
125
126                let mib = $id::mib().unwrap();
127                let _ = mib.write($ret_ty::default()).unwrap();
128
129                #[cfg(feature = "use_std")]
130                println!(
131                    concat!(
132                        stringify!($id),
133                        " (write): \"{}\""),
134                    $ret_ty::default()
135                );
136
137            }
138        }
139    };
140}
141
142/// Update
143macro_rules! u {
144    ($id:ident  => $ret_ty:ty) => {
145        paste::paste! {
146            impl $id {
147                /// Updates key to `value` returning its old value using string API.
148                pub fn update(value: $ret_ty) -> crate::error::Result<$ret_ty> {
149                    use crate::keys::Access;
150                    Self::NAME.update(value)
151                }
152            }
153
154            impl [<$id _mib>] {
155                /// Updates key to `value` returning its old value using MIB API.
156                pub fn update(self, value: $ret_ty) -> crate::error::Result<$ret_ty> {
157                    use crate::keys::Access;
158                    self.0.update(value)
159                }
160            }
161
162            #[cfg(test)]
163            #[test]
164            #[cfg(not(target_arch = "mips64el"))]
165            #[allow(unused)]
166            fn [<$id _update_test>]() {
167                match stringify!($id) {
168                    "background_thread" |
169                    "max_background_threads"
170                        if cfg!(target_os = "macos") => return,
171                    _ => (),
172                }
173
174                let a = $id::update($ret_ty::default()).unwrap();
175
176                let mib = $id::mib().unwrap();
177                let b = mib.update($ret_ty::default()).unwrap();
178
179                #[cfg(feature = "use_std")]
180                println!(
181                    concat!(
182                        stringify!($id),
183                        " (update): (\"{}\", \"{}\") - \"{}\""),
184                    a, b, $ret_ty::default()
185                );
186            }
187        }
188    };
189}
190
191/// Creates a new option
192macro_rules! option {
193    ($id:ident[ str: $byte_string:expr, $mib:ty, $name_to_mib:ident ] => $ret_ty:ty |
194     ops: $($ops:ident),* |
195     docs:
196     $(#[$doc:meta])*
197     mib_docs:
198     $(#[$doc_mib:meta])*
199    ) => {
200        types! {
201            $id[ str: $byte_string, $mib, $name_to_mib ] |
202            docs: $(#[$doc])*
203            mib_docs: $(#[$doc_mib])*
204        }
205        $(
206            $ops!($id => $ret_ty);
207        )*
208    };
209    // Non-string option:
210    ($id:ident[ str: $byte_string:expr, non_str: $mib_len:expr ] => $ret_ty:ty |
211     ops: $($ops:ident),* |
212     docs:
213     $(#[$doc:meta])*
214     mib_docs:
215     $(#[$doc_mib:meta])*
216    ) => {
217        option! {
218            $id[ str: $byte_string, Mib<[usize; $mib_len]>, mib ] => $ret_ty |
219            ops: $($ops),* |
220            docs: $(#[$doc])*
221            mib_docs: $(#[$doc_mib])*
222        }
223    };
224    // String option:
225    ($id:ident[ str: $byte_string:expr, str: $mib_len:expr ] => $ret_ty:ty |
226     ops: $($ops:ident),* |
227     docs:
228     $(#[$doc:meta])*
229     mib_docs:
230     $(#[$doc_mib:meta])*
231    ) => {
232        option! {
233            $id[ str: $byte_string, MibStr<[usize; $mib_len]>, mib_str ] => $ret_ty |
234            ops: $($ops),* |
235            docs: $(#[$doc])*
236            mib_docs: $(#[$doc_mib])*
237        }
238    };
239}