1 | // Copyright 2016 Brian Smith. |
2 | // |
3 | // Permission to use, copy, modify, and/or distribute this software for any |
4 | // purpose with or without fee is hereby granted, provided that the above |
5 | // copyright notice and this permission notice appear in all copies. |
6 | // |
7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES |
8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY |
10 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
12 | // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
13 | // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
14 | |
15 | /// A witness indicating that CPU features have been detected and cached. |
16 | /// |
17 | /// TODO: Eventually all feature detection logic should be done through |
18 | /// functions that accept a `Features` parameter, to guarantee that nothing |
19 | /// tries to read the cached values before they are written. |
20 | /// |
21 | /// This is a zero-sized type so that it can be "stored" wherever convenient. |
22 | #[derive (Copy, Clone)] |
23 | pub(crate) struct Features(()); |
24 | |
25 | #[inline (always)] |
26 | pub(crate) fn features() -> Features { |
27 | #[cfg (any(target_arch = "aarch64" , target_arch = "arm" ))] |
28 | use arm::init_global_shared_with_assembly; |
29 | |
30 | #[cfg (any(target_arch = "x86" , target_arch = "x86_64" ))] |
31 | use intel::init_global_shared_with_assembly; |
32 | |
33 | #[cfg (any( |
34 | target_arch = "aarch64" , |
35 | target_arch = "arm" , |
36 | target_arch = "x86" , |
37 | target_arch = "x86_64" , |
38 | ))] |
39 | { |
40 | static INIT: spin::Once<()> = spin::Once::new(); |
41 | let () = INIT.call_once(|| unsafe { init_global_shared_with_assembly() }); |
42 | } |
43 | |
44 | Features(()) |
45 | } |
46 | |
47 | #[cfg (any(target_arch = "aarch64" , target_arch = "arm" ))] |
48 | pub mod arm; |
49 | |
50 | #[cfg (any(target_arch = "x86" , target_arch = "x86_64" ))] |
51 | pub mod intel; |
52 | |