aboutsummaryrefslogtreecommitdiff
path: root/vendor/rustix/src/backend/libc/mm
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/libc/mm')
-rw-r--r--vendor/rustix/src/backend/libc/mm/mod.rs2
-rw-r--r--vendor/rustix/src/backend/libc/mm/syscalls.rs244
-rw-r--r--vendor/rustix/src/backend/libc/mm/types.rs477
3 files changed, 723 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/libc/mm/mod.rs b/vendor/rustix/src/backend/libc/mm/mod.rs
new file mode 100644
index 0000000..1e0181a
--- /dev/null
+++ b/vendor/rustix/src/backend/libc/mm/mod.rs
@@ -0,0 +1,2 @@
+pub(crate) mod syscalls;
+pub(crate) mod types;
diff --git a/vendor/rustix/src/backend/libc/mm/syscalls.rs b/vendor/rustix/src/backend/libc/mm/syscalls.rs
new file mode 100644
index 0000000..33bc9ca
--- /dev/null
+++ b/vendor/rustix/src/backend/libc/mm/syscalls.rs
@@ -0,0 +1,244 @@
+//! libc syscalls supporting `rustix::mm`.
+
+#[cfg(not(target_os = "redox"))]
+use super::types::Advice;
+#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
+use super::types::MlockAllFlags;
+#[cfg(any(target_os = "emscripten", target_os = "linux"))]
+use super::types::MremapFlags;
+use super::types::{MapFlags, MprotectFlags, MsyncFlags, ProtFlags};
+#[cfg(linux_kernel)]
+use super::types::{MlockFlags, UserfaultfdFlags};
+use crate::backend::c;
+#[cfg(linux_kernel)]
+use crate::backend::conv::ret_owned_fd;
+use crate::backend::conv::{borrowed_fd, no_fd, ret};
+use crate::fd::BorrowedFd;
+#[cfg(linux_kernel)]
+use crate::fd::OwnedFd;
+use crate::io;
+
+#[cfg(not(target_os = "redox"))]
+pub(crate) fn madvise(addr: *mut c::c_void, len: usize, advice: Advice) -> io::Result<()> {
+ // On Linux platforms, `MADV_DONTNEED` has the same value as
+ // `POSIX_MADV_DONTNEED` but different behavior. We remap it to a different
+ // value, and check for it here.
+ #[cfg(target_os = "linux")]
+ if let Advice::LinuxDontNeed = advice {
+ return unsafe { ret(c::madvise(addr, len, c::MADV_DONTNEED)) };
+ }
+
+ #[cfg(not(target_os = "android"))]
+ {
+ let err = unsafe { c::posix_madvise(addr, len, advice as c::c_int) };
+
+ // `posix_madvise` returns its error status rather than using `errno`.
+ if err == 0 {
+ Ok(())
+ } else {
+ Err(io::Errno(err))
+ }
+ }
+
+ #[cfg(target_os = "android")]
+ {
+ if let Advice::DontNeed = advice {
+ // Do nothing. Linux's `MADV_DONTNEED` isn't the same as
+ // `POSIX_MADV_DONTNEED`, so just discard `MADV_DONTNEED`.
+ Ok(())
+ } else {
+ unsafe { ret(c::madvise(addr, len, advice as c::c_int)) }
+ }
+ }
+}
+
+pub(crate) unsafe fn msync(addr: *mut c::c_void, len: usize, flags: MsyncFlags) -> io::Result<()> {
+ let err = c::msync(addr, len, bitflags_bits!(flags));
+
+ // `msync` returns its error status rather than using `errno`.
+ if err == 0 {
+ Ok(())
+ } else {
+ Err(io::Errno(err))
+ }
+}
+
+/// # Safety
+///
+/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
+/// with memory pointed to by raw pointers is unsafe.
+pub(crate) unsafe fn mmap(
+ ptr: *mut c::c_void,
+ len: usize,
+ prot: ProtFlags,
+ flags: MapFlags,
+ fd: BorrowedFd<'_>,
+ offset: u64,
+) -> io::Result<*mut c::c_void> {
+ let res = c::mmap(
+ ptr,
+ len,
+ bitflags_bits!(prot),
+ bitflags_bits!(flags),
+ borrowed_fd(fd),
+ offset as i64,
+ );
+ if res == c::MAP_FAILED {
+ Err(io::Errno::last_os_error())
+ } else {
+ Ok(res)
+ }
+}
+
+/// # Safety
+///
+/// `mmap` is primarily unsafe due to the `addr` parameter, as anything working
+/// with memory pointed to by raw pointers is unsafe.
+pub(crate) unsafe fn mmap_anonymous(
+ ptr: *mut c::c_void,
+ len: usize,
+ prot: ProtFlags,
+ flags: MapFlags,
+) -> io::Result<*mut c::c_void> {
+ let res = c::mmap(
+ ptr,
+ len,
+ bitflags_bits!(prot),
+ bitflags_bits!(flags | MapFlags::from_bits_retain(bitcast!(c::MAP_ANONYMOUS))),
+ no_fd(),
+ 0,
+ );
+ if res == c::MAP_FAILED {
+ Err(io::Errno::last_os_error())
+ } else {
+ Ok(res)
+ }
+}
+
+pub(crate) unsafe fn mprotect(
+ ptr: *mut c::c_void,
+ len: usize,
+ flags: MprotectFlags,
+) -> io::Result<()> {
+ ret(c::mprotect(ptr, len, bitflags_bits!(flags)))
+}
+
+pub(crate) unsafe fn munmap(ptr: *mut c::c_void, len: usize) -> io::Result<()> {
+ ret(c::munmap(ptr, len))
+}
+
+/// # Safety
+///
+/// `mremap` is primarily unsafe due to the `old_address` parameter, as
+/// anything working with memory pointed to by raw pointers is unsafe.
+#[cfg(any(target_os = "emscripten", target_os = "linux"))]
+pub(crate) unsafe fn mremap(
+ old_address: *mut c::c_void,
+ old_size: usize,
+ new_size: usize,
+ flags: MremapFlags,
+) -> io::Result<*mut c::c_void> {
+ let res = c::mremap(old_address, old_size, new_size, bitflags_bits!(flags));
+ if res == c::MAP_FAILED {
+ Err(io::Errno::last_os_error())
+ } else {
+ Ok(res)
+ }
+}
+
+/// # Safety
+///
+/// `mremap_fixed` is primarily unsafe due to the `old_address` and
+/// `new_address` parameters, as anything working with memory pointed to by raw
+/// pointers is unsafe.
+#[cfg(any(target_os = "emscripten", target_os = "linux"))]
+pub(crate) unsafe fn mremap_fixed(
+ old_address: *mut c::c_void,
+ old_size: usize,
+ new_size: usize,
+ flags: MremapFlags,
+ new_address: *mut c::c_void,
+) -> io::Result<*mut c::c_void> {
+ let res = c::mremap(
+ old_address,
+ old_size,
+ new_size,
+ bitflags_bits!(flags | MremapFlags::from_bits_retain(bitcast!(c::MAP_FIXED))),
+ new_address,
+ );
+ if res == c::MAP_FAILED {
+ Err(io::Errno::last_os_error())
+ } else {
+ Ok(res)
+ }
+}
+
+/// # Safety
+///
+/// `mlock` operates on raw pointers and may round out to the nearest page
+/// boundaries.
+#[inline]
+pub(crate) unsafe fn mlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
+ ret(c::mlock(addr, length))
+}
+
+/// # Safety
+///
+/// `mlock_with` operates on raw pointers and may round out to the nearest page
+/// boundaries.
+#[cfg(linux_kernel)]
+#[inline]
+pub(crate) unsafe fn mlock_with(
+ addr: *mut c::c_void,
+ length: usize,
+ flags: MlockFlags,
+) -> io::Result<()> {
+ weak_or_syscall! {
+ fn mlock2(
+ addr: *const c::c_void,
+ len: c::size_t,
+ flags: c::c_int
+ ) via SYS_mlock2 -> c::c_int
+ }
+
+ ret(mlock2(addr, length, bitflags_bits!(flags)))
+}
+
+/// # Safety
+///
+/// `munlock` operates on raw pointers and may round out to the nearest page
+/// boundaries.
+#[inline]
+pub(crate) unsafe fn munlock(addr: *mut c::c_void, length: usize) -> io::Result<()> {
+ ret(c::munlock(addr, length))
+}
+
+#[cfg(linux_kernel)]
+pub(crate) unsafe fn userfaultfd(flags: UserfaultfdFlags) -> io::Result<OwnedFd> {
+ syscall! {
+ fn userfaultfd(
+ flags: c::c_int
+ ) via SYS_userfaultfd -> c::c_int
+ }
+ ret_owned_fd(userfaultfd(bitflags_bits!(flags)))
+}
+
+/// Locks all pages mapped into the address space of the calling process.
+///
+/// This includes the pages of the code, data, and stack segment, as well as
+/// shared libraries, user space kernel data, shared memory, and memory-mapped
+/// files. All mapped pages are guaranteed to be resident in RAM when the call
+/// returns successfully; the pages are guaranteed to stay in RAM until later
+/// unlocked.
+#[inline]
+#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
+pub(crate) fn mlockall(flags: MlockAllFlags) -> io::Result<()> {
+ unsafe { ret(c::mlockall(bitflags_bits!(flags))) }
+}
+
+/// Unlocks all pages mapped into the address space of the calling process.
+#[inline]
+#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
+pub(crate) fn munlockall() -> io::Result<()> {
+ unsafe { ret(c::munlockall()) }
+}
diff --git a/vendor/rustix/src/backend/libc/mm/types.rs b/vendor/rustix/src/backend/libc/mm/types.rs
new file mode 100644
index 0000000..a4aa3e2
--- /dev/null
+++ b/vendor/rustix/src/backend/libc/mm/types.rs
@@ -0,0 +1,477 @@
+use crate::backend::c;
+use bitflags::bitflags;
+
+bitflags! {
+ /// `PROT_*` flags for use with [`mmap`].
+ ///
+ /// For `PROT_NONE`, use `ProtFlags::empty()`.
+ ///
+ /// [`mmap`]: crate::mm::mmap
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct ProtFlags: u32 {
+ /// `PROT_READ`
+ const READ = bitcast!(c::PROT_READ);
+ /// `PROT_WRITE`
+ const WRITE = bitcast!(c::PROT_WRITE);
+ /// `PROT_EXEC`
+ const EXEC = bitcast!(c::PROT_EXEC);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `PROT_*` flags for use with [`mprotect`].
+ ///
+ /// For `PROT_NONE`, use `MprotectFlags::empty()`.
+ ///
+ /// [`mprotect`]: crate::mm::mprotect
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MprotectFlags: u32 {
+ /// `PROT_READ`
+ const READ = bitcast!(c::PROT_READ);
+ /// `PROT_WRITE`
+ const WRITE = bitcast!(c::PROT_WRITE);
+ /// `PROT_EXEC`
+ const EXEC = bitcast!(c::PROT_EXEC);
+ /// `PROT_GROWSUP`
+ #[cfg(linux_kernel)]
+ const GROWSUP = bitcast!(c::PROT_GROWSUP);
+ /// `PROT_GROWSDOWN`
+ #[cfg(linux_kernel)]
+ const GROWSDOWN = bitcast!(c::PROT_GROWSDOWN);
+ /// `PROT_SEM`
+ #[cfg(linux_kernel)]
+ const SEM = linux_raw_sys::general::PROT_SEM;
+ /// `PROT_BTI`
+ #[cfg(all(linux_kernel, target_arch = "aarch64"))]
+ const BTI = linux_raw_sys::general::PROT_BTI;
+ /// `PROT_MTE`
+ #[cfg(all(linux_kernel, target_arch = "aarch64"))]
+ const MTE = linux_raw_sys::general::PROT_MTE;
+ /// `PROT_SAO`
+ #[cfg(all(linux_kernel, any(target_arch = "powerpc", target_arch = "powerpc64")))]
+ const SAO = linux_raw_sys::general::PROT_SAO;
+ /// `PROT_ADI`
+ #[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))]
+ const ADI = linux_raw_sys::general::PROT_ADI;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `MAP_*` flags for use with [`mmap`].
+ ///
+ /// For `MAP_ANONYMOUS` (aka `MAP_ANON`), see [`mmap_anonymous`].
+ ///
+ /// [`mmap`]: crate::mm::mmap
+ /// [`mmap_anonymous`]: crates::mm::mmap_anonymous
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MapFlags: u32 {
+ /// `MAP_SHARED`
+ const SHARED = bitcast!(c::MAP_SHARED);
+ /// `MAP_SHARED_VALIDATE`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const SHARED_VALIDATE = bitcast!(c::MAP_SHARED_VALIDATE);
+ /// `MAP_PRIVATE`
+ const PRIVATE = bitcast!(c::MAP_PRIVATE);
+ /// `MAP_DENYWRITE`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const DENYWRITE = bitcast!(c::MAP_DENYWRITE);
+ /// `MAP_FIXED`
+ const FIXED = bitcast!(c::MAP_FIXED);
+ /// `MAP_FIXED_NOREPLACE`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const FIXED_NOREPLACE = bitcast!(c::MAP_FIXED_NOREPLACE);
+ /// `MAP_GROWSDOWN`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const GROWSDOWN = bitcast!(c::MAP_GROWSDOWN);
+ /// `MAP_HUGETLB`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const HUGETLB = bitcast!(c::MAP_HUGETLB);
+ /// `MAP_HUGE_2MB`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const HUGE_2MB = bitcast!(c::MAP_HUGE_2MB);
+ /// `MAP_HUGE_1GB`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const HUGE_1GB = bitcast!(c::MAP_HUGE_1GB);
+ /// `MAP_LOCKED`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const LOCKED = bitcast!(c::MAP_LOCKED);
+ /// `MAP_NOCORE`
+ #[cfg(freebsdlike)]
+ const NOCORE = bitcast!(c::MAP_NOCORE);
+ /// `MAP_NORESERVE`
+ #[cfg(not(any(
+ freebsdlike,
+ target_os = "aix",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const NORESERVE = bitcast!(c::MAP_NORESERVE);
+ /// `MAP_NOSYNC`
+ #[cfg(freebsdlike)]
+ const NOSYNC = bitcast!(c::MAP_NOSYNC);
+ /// `MAP_POPULATE`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ )))]
+ const POPULATE = bitcast!(c::MAP_POPULATE);
+ /// `MAP_STACK`
+ #[cfg(not(any(
+ apple,
+ solarish,
+ target_os = "aix",
+ target_os = "dragonfly",
+ target_os = "haiku",
+ target_os = "netbsd",
+ target_os = "redox",
+ )))]
+ const STACK = bitcast!(c::MAP_STACK);
+ /// `MAP_PREFAULT_READ`
+ #[cfg(target_os = "freebsd")]
+ const PREFAULT_READ = bitcast!(c::MAP_PREFAULT_READ);
+ /// `MAP_SYNC`
+ #[cfg(not(any(
+ bsd,
+ solarish,
+ target_os = "aix",
+ target_os = "android",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "haiku",
+ target_os = "nto",
+ target_os = "redox",
+ all(
+ linux_kernel,
+ any(target_arch = "mips", target_arch = "mips32r6", target_arch = "mips64", target_arch = "mips64r6"),
+ )
+ )))]
+ const SYNC = bitcast!(c::MAP_SYNC);
+ /// `MAP_UNINITIALIZED`
+ #[cfg(any())]
+ const UNINITIALIZED = bitcast!(c::MAP_UNINITIALIZED);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+#[cfg(any(target_os = "emscripten", target_os = "linux"))]
+bitflags! {
+ /// `MREMAP_*` flags for use with [`mremap`].
+ ///
+ /// For `MREMAP_FIXED`, see [`mremap_fixed`].
+ ///
+ /// [`mremap`]: crate::mm::mremap
+ /// [`mremap_fixed`]: crate::mm::mremap_fixed
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MremapFlags: u32 {
+ /// `MREMAP_MAYMOVE`
+ const MAYMOVE = bitcast!(c::MREMAP_MAYMOVE);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `MS_*` flags for use with [`msync`].
+ ///
+ /// [`msync`]: crate::mm::msync
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MsyncFlags: u32 {
+ /// `MS_SYNC`—Requests an update and waits for it to complete.
+ const SYNC = bitcast!(c::MS_SYNC);
+ /// `MS_ASYNC`—Specifies that an update be scheduled, but the call
+ /// returns immediately.
+ const ASYNC = bitcast!(c::MS_ASYNC);
+ /// `MS_INVALIDATE`—Asks to invalidate other mappings of the same
+ /// file (so that they can be updated with the fresh values just
+ /// written).
+ const INVALIDATE = bitcast!(c::MS_INVALIDATE);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+#[cfg(linux_kernel)]
+bitflags! {
+ /// `MLOCK_*` flags for use with [`mlock_with`].
+ ///
+ /// [`mlock_with`]: crate::mm::mlock_with
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MlockFlags: u32 {
+ /// `MLOCK_ONFAULT`
+ const ONFAULT = bitcast!(c::MLOCK_ONFAULT);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+/// `POSIX_MADV_*` constants for use with [`madvise`].
+///
+/// [`madvise`]: crate::mm::madvise
+#[cfg(not(target_os = "redox"))]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum Advice {
+ /// `POSIX_MADV_NORMAL`
+ #[cfg(not(any(target_os = "android", target_os = "haiku")))]
+ Normal = bitcast!(c::POSIX_MADV_NORMAL),
+
+ /// `POSIX_MADV_NORMAL`
+ #[cfg(any(target_os = "android", target_os = "haiku"))]
+ Normal = bitcast!(c::MADV_NORMAL),
+
+ /// `POSIX_MADV_SEQUENTIAL`
+ #[cfg(not(any(target_os = "android", target_os = "haiku")))]
+ Sequential = bitcast!(c::POSIX_MADV_SEQUENTIAL),
+
+ /// `POSIX_MADV_SEQUENTIAL`
+ #[cfg(any(target_os = "android", target_os = "haiku"))]
+ Sequential = bitcast!(c::MADV_SEQUENTIAL),
+
+ /// `POSIX_MADV_RANDOM`
+ #[cfg(not(any(target_os = "android", target_os = "haiku")))]
+ Random = bitcast!(c::POSIX_MADV_RANDOM),
+
+ /// `POSIX_MADV_RANDOM`
+ #[cfg(any(target_os = "android", target_os = "haiku"))]
+ Random = bitcast!(c::MADV_RANDOM),
+
+ /// `POSIX_MADV_WILLNEED`
+ #[cfg(not(any(target_os = "android", target_os = "haiku")))]
+ WillNeed = bitcast!(c::POSIX_MADV_WILLNEED),
+
+ /// `POSIX_MADV_WILLNEED`
+ #[cfg(any(target_os = "android", target_os = "haiku"))]
+ WillNeed = bitcast!(c::MADV_WILLNEED),
+
+ /// `POSIX_MADV_DONTNEED`
+ #[cfg(not(any(target_os = "android", target_os = "emscripten", target_os = "haiku")))]
+ DontNeed = bitcast!(c::POSIX_MADV_DONTNEED),
+
+ /// `POSIX_MADV_DONTNEED`
+ #[cfg(any(target_os = "android", target_os = "haiku"))]
+ DontNeed = bitcast!(i32::MAX - 1),
+
+ /// `MADV_DONTNEED`
+ // `MADV_DONTNEED` has the same value as `POSIX_MADV_DONTNEED`. We don't
+ // have a separate `posix_madvise` from `madvise`, so we expose a special
+ // value which we special-case.
+ #[cfg(target_os = "linux")]
+ LinuxDontNeed = bitcast!(i32::MAX),
+
+ /// `MADV_DONTNEED`
+ #[cfg(target_os = "android")]
+ LinuxDontNeed = bitcast!(c::MADV_DONTNEED),
+ /// `MADV_FREE`
+ #[cfg(linux_kernel)]
+ LinuxFree = bitcast!(c::MADV_FREE),
+ /// `MADV_REMOVE`
+ #[cfg(linux_kernel)]
+ LinuxRemove = bitcast!(c::MADV_REMOVE),
+ /// `MADV_DONTFORK`
+ #[cfg(linux_kernel)]
+ LinuxDontFork = bitcast!(c::MADV_DONTFORK),
+ /// `MADV_DOFORK`
+ #[cfg(linux_kernel)]
+ LinuxDoFork = bitcast!(c::MADV_DOFORK),
+ /// `MADV_HWPOISON`
+ #[cfg(linux_kernel)]
+ LinuxHwPoison = bitcast!(c::MADV_HWPOISON),
+ /// `MADV_SOFT_OFFLINE`
+ #[cfg(all(
+ linux_kernel,
+ not(any(
+ target_arch = "mips",
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6"
+ ))
+ ))]
+ LinuxSoftOffline = bitcast!(c::MADV_SOFT_OFFLINE),
+ /// `MADV_MERGEABLE`
+ #[cfg(linux_kernel)]
+ LinuxMergeable = bitcast!(c::MADV_MERGEABLE),
+ /// `MADV_UNMERGEABLE`
+ #[cfg(linux_kernel)]
+ LinuxUnmergeable = bitcast!(c::MADV_UNMERGEABLE),
+ /// `MADV_HUGEPAGE`
+ #[cfg(linux_kernel)]
+ LinuxHugepage = bitcast!(c::MADV_HUGEPAGE),
+ /// `MADV_NOHUGEPAGE`
+ #[cfg(linux_kernel)]
+ LinuxNoHugepage = bitcast!(c::MADV_NOHUGEPAGE),
+ /// `MADV_DONTDUMP` (since Linux 3.4)
+ #[cfg(linux_kernel)]
+ LinuxDontDump = bitcast!(c::MADV_DONTDUMP),
+ /// `MADV_DODUMP` (since Linux 3.4)
+ #[cfg(linux_kernel)]
+ LinuxDoDump = bitcast!(c::MADV_DODUMP),
+ /// `MADV_WIPEONFORK` (since Linux 4.14)
+ #[cfg(linux_kernel)]
+ LinuxWipeOnFork = bitcast!(c::MADV_WIPEONFORK),
+ /// `MADV_KEEPONFORK` (since Linux 4.14)
+ #[cfg(linux_kernel)]
+ LinuxKeepOnFork = bitcast!(c::MADV_KEEPONFORK),
+ /// `MADV_COLD` (since Linux 5.4)
+ #[cfg(linux_kernel)]
+ LinuxCold = bitcast!(c::MADV_COLD),
+ /// `MADV_PAGEOUT` (since Linux 5.4)
+ #[cfg(linux_kernel)]
+ LinuxPageOut = bitcast!(c::MADV_PAGEOUT),
+ /// `MADV_POPULATE_READ` (since Linux 5.14)
+ #[cfg(linux_kernel)]
+ LinuxPopulateRead = bitcast!(c::MADV_POPULATE_READ),
+ /// `MADV_POPULATE_WRITE` (since Linux 5.14)
+ #[cfg(linux_kernel)]
+ LinuxPopulateWrite = bitcast!(c::MADV_POPULATE_WRITE),
+ /// `MADV_DONTNEED_LOCKED` (since Linux 5.18)
+ #[cfg(linux_kernel)]
+ LinuxDontneedLocked = bitcast!(c::MADV_DONTNEED_LOCKED),
+}
+
+#[cfg(target_os = "emscripten")]
+#[allow(non_upper_case_globals)]
+impl Advice {
+ /// `POSIX_MADV_DONTNEED`
+ pub const DontNeed: Self = Self::Normal;
+}
+
+#[cfg(linux_kernel)]
+bitflags! {
+ /// `O_*` flags for use with [`userfaultfd`].
+ ///
+ /// [`userfaultfd`]: crate::mm::userfaultfd
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct UserfaultfdFlags: u32 {
+ /// `O_CLOEXEC`
+ const CLOEXEC = bitcast!(c::O_CLOEXEC);
+ /// `O_NONBLOCK`
+ const NONBLOCK = bitcast!(c::O_NONBLOCK);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+#[cfg(any(linux_kernel, freebsdlike, netbsdlike))]
+bitflags! {
+ /// `MCL_*` flags for use with [`mlockall`].
+ ///
+ /// [`mlockall`]: crate::mm::mlockall
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct MlockAllFlags: u32 {
+ /// Used together with `MCL_CURRENT`, `MCL_FUTURE`, or both. Mark all
+ /// current (with `MCL_CURRENT`) or future (with `MCL_FUTURE`) mappings
+ /// to lock pages when they are faulted in. When used with
+ /// `MCL_CURRENT`, all present pages are locked, but `mlockall` will
+ /// not fault in non-present pages. When used with `MCL_FUTURE`, all
+ /// future mappings will be marked to lock pages when they are faulted
+ /// in, but they will not be populated by the lock when the mapping is
+ /// created. `MCL_ONFAULT` must be used with either `MCL_CURRENT` or
+ /// `MCL_FUTURE` or both.
+ #[cfg(linux_kernel)]
+ const ONFAULT = bitcast!(libc::MCL_ONFAULT);
+ /// Lock all pages which will become mapped into the address space of
+ /// the process in the future. These could be, for instance, new pages
+ /// required by a growing heap and stack as well as new memory-mapped
+ /// files or shared memory regions.
+ const FUTURE = bitcast!(libc::MCL_FUTURE);
+ /// Lock all pages which are currently mapped into the address space of
+ /// the process.
+ const CURRENT = bitcast!(libc::MCL_CURRENT);
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}