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