]>
Commit | Line | Data |
---|---|---|
fe692bf9 FG |
1 | //! The Linux `membarrier` syscall. |
2 | //! | |
3 | //! # Safety | |
4 | //! | |
5 | //! This file defines an enum and a bitflags type that represent the same | |
6 | //! set of values and are kept in sync. | |
7 | #![allow(unsafe_code)] | |
8 | ||
9 | use crate::process::Cpuid; | |
10 | use crate::{backend, io}; | |
11 | ||
12 | pub use backend::process::types::MembarrierCommand; | |
13 | ||
14 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
15 | bitflags::bitflags! { | |
16 | /// A result from [`membarrier_query`]. | |
17 | /// | |
18 | /// These flags correspond to values of [`MembarrierCommand`] which are | |
19 | /// supported in the OS. | |
20 | pub struct MembarrierQuery: u32 { | |
21 | /// `MEMBARRIER_CMD_GLOBAL` | |
22 | #[doc(alias = "SHARED")] | |
23 | #[doc(alias = "MEMBARRIER_CMD_SHARED")] | |
24 | const GLOBAL = MembarrierCommand::Global as _; | |
25 | /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` | |
26 | const GLOBAL_EXPEDITED = MembarrierCommand::GlobalExpedited as _; | |
27 | /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` | |
28 | const REGISTER_GLOBAL_EXPEDITED = MembarrierCommand::RegisterGlobalExpedited as _; | |
29 | /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` | |
30 | const PRIVATE_EXPEDITED = MembarrierCommand::PrivateExpedited as _; | |
31 | /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` | |
32 | const REGISTER_PRIVATE_EXPEDITED = MembarrierCommand::RegisterPrivateExpedited as _; | |
33 | /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` | |
34 | const PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::PrivateExpeditedSyncCore as _; | |
35 | /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` | |
36 | const REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::RegisterPrivateExpeditedSyncCore as _; | |
37 | /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) | |
38 | const PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::PrivateExpeditedRseq as _; | |
39 | /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) | |
40 | const REGISTER_PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::RegisterPrivateExpeditedRseq as _; | |
41 | } | |
42 | } | |
43 | ||
44 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
45 | impl MembarrierQuery { | |
46 | /// Test whether this query result contains the given command. | |
47 | #[inline] | |
48 | pub fn contains_command(self, cmd: MembarrierCommand) -> bool { | |
49 | // SAFETY: `MembarrierCommand` is an enum that only contains values | |
50 | // also valid in `MembarrierQuery`. | |
51 | self.contains(unsafe { Self::from_bits_unchecked(cmd as _) }) | |
52 | } | |
53 | } | |
54 | ||
55 | /// `membarrier(MEMBARRIER_CMD_QUERY, 0, 0)`—Query the supported `membarrier` | |
56 | /// commands. | |
57 | /// | |
58 | /// This function doesn't return a `Result` because it always succeeds; if | |
59 | /// the underlying OS doesn't support the `membarrier` syscall, it returns | |
60 | /// an empty `MembarrierQuery` value. | |
61 | /// | |
62 | /// # References | |
63 | /// - [Linux] | |
64 | /// | |
65 | /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html | |
66 | #[inline] | |
67 | #[doc(alias = "MEMBARRIER_CMD_QUERY")] | |
68 | pub fn membarrier_query() -> MembarrierQuery { | |
69 | backend::process::syscalls::membarrier_query() | |
70 | } | |
71 | ||
72 | /// `membarrier(cmd, 0, 0)`—Perform a memory barrier. | |
73 | /// | |
74 | /// # References | |
75 | /// - [Linux] | |
76 | /// | |
77 | /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html | |
78 | #[inline] | |
79 | pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { | |
80 | backend::process::syscalls::membarrier(cmd) | |
81 | } | |
82 | ||
83 | /// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier | |
84 | /// with a specific CPU. | |
85 | /// | |
86 | /// # References | |
87 | /// - [Linux] | |
88 | /// | |
89 | /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html | |
90 | #[inline] | |
91 | pub fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { | |
92 | backend::process::syscalls::membarrier_cpu(cmd, cpu) | |
93 | } |