1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Memory operations.
use std::io;
use crate::op::operation;
use crate::{SubmissionQueue, man_link, new_flag, sys};
/// Give advice about use of memory.
///
/// Give advice or directions to the kernel about the address range beginning at
/// address `addr` and with size `length` bytes. In most cases, the goal of such
/// advice is to improve system or application performance.
#[doc = man_link!(madvise(2))]
#[doc(alias = "madvise")]
#[doc(alias = "posix_madvise")]
pub fn advise(sq: SubmissionQueue, address: *mut (), length: u32, advice: AdviseFlag) -> Advise {
Advise::new(sq, (), (address, length, advice))
}
new_flag!(
/// Advise about memory access.
///
/// See [`advise`].
pub struct AdviseFlag(u32) {
/// No special treatment.
NORMAL = libc::MADV_NORMAL,
/// Expect page references in random order.
RANDOM = libc::MADV_RANDOM,
/// Expect page references in sequential order.
SEQUENTIAL = libc::MADV_SEQUENTIAL,
/// Expect access in the near future.
WILL_NEED = libc::MADV_WILLNEED,
/// Do not expect access in the near future.
DONT_NEED = libc::MADV_DONTNEED,
/// Free up a given range of pages and its associated backing store.
#[cfg(any(target_os = "android", target_os = "linux"))]
REMOVE = libc::MADV_REMOVE,
/// Do not make the pages in this range available to the child after a
/// `fork(2)`.
#[cfg(any(target_os = "android", target_os = "linux"))]
DONT_FORK = libc::MADV_DONTFORK,
/// Undo the effect of `DONT_FORK`, restoring the default behavior,
/// whereby a mapping is inherited across `fork(2)`.
#[cfg(any(target_os = "android", target_os = "linux"))]
DO_FORK = libc::MADV_DOFORK,
/// Poison the pages and handle subsequent references to those pages
/// like a hardware memory corruption.
#[cfg(any(target_os = "android", target_os = "linux"))]
HW_POISON = libc::MADV_HWPOISON,
/// Enable Kernel Samepage Merging (KSM) for the pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
MERGEABLE = libc::MADV_MERGEABLE,
/// Undo the effect of an earlier `MERGEABLE` operation.
#[cfg(any(target_os = "android", target_os = "linux"))]
UNMERGEABLE = libc::MADV_UNMERGEABLE,
/// Soft offline the pages in the range.
#[cfg(any(target_os = "android", target_os = "linux"))]
SOFT_OFFLINE = libc::MADV_SOFT_OFFLINE,
/// Enable Transparent Huge Pages (THP) for pages in the range.
#[cfg(any(target_os = "android", target_os = "linux"))]
HUGE_PAGE = libc::MADV_HUGEPAGE,
/// Ensures that memory in the address range will not be backed by
/// transparent hugepages.
#[cfg(any(target_os = "android", target_os = "linux"))]
NO_HUGE_PAGE = libc::MADV_NOHUGEPAGE,
/// Perform a best-effort collapse of the native pages mapped by the
/// memory range into Transparent Huge Pages (THPs).
#[cfg(any(target_os = "android", target_os = "linux"))]
COLLAPSE = libc::MADV_COLLAPSE,
/// Exclude from a core dump those pages in the range.
#[cfg(any(target_os = "android", target_os = "linux"))]
DONT_DUMP = libc::MADV_DONTDUMP,
/// Undo the effect of an earlier `DONT_DUMP`.
#[cfg(any(target_os = "android", target_os = "linux"))]
DO_DUMP = libc::MADV_DODUMP,
/// The application no longer requires the pages in the range.
FREE = libc::MADV_FREE,
/// Present the child process with zero-filled memory in this range
/// after a `fork(2)`.
#[cfg(any(target_os = "android", target_os = "linux"))]
WIPE_ON_FORK = libc::MADV_WIPEONFORK,
/// Undo the effect of an earlier `WIPE_ON_FORK`.
#[cfg(any(target_os = "android", target_os = "linux"))]
KEEP_ON_FORK = libc::MADV_KEEPONFORK,
/// Deactivate a given range of pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
COLD = libc::MADV_COLD,
/// Reclaim a given range of pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
PAGE_OUT = libc::MADV_PAGEOUT,
/// Populate (prefault) page tables readable, faulting in all pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
POPULATE_READ = libc::MADV_POPULATE_READ,
/// Populate (prefault) page tables writable, faulting in all pages.
#[cfg(any(target_os = "android", target_os = "linux"))]
POPULATE_WRITE = libc::MADV_POPULATE_WRITE,
/// Zero out the pages in the address range if it is deallocated without
/// first unwiring the pages (i.e. a munmap(2) without a preceding
/// munlock(2) or the application quits).
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "visionos", target_os = "watchos"))]
ZERO_WIRED_PAGES = libc::MADV_ZERO_WIRED_PAGES,
/// Zero out the pages in the address range without causing unnecessary
/// memory accesses.
///
/// This could return `ENOTSUP` in some situations, in which case the
/// caller should fall back to zeroing the range themselves.
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "visionos", target_os = "watchos"))]
ZERO = libc::MADV_ZERO,
/// Don't flush the data associated with this map to physical backing
/// store unless it needs to.
#[cfg(target_os = "freebsd")]
NO_SYNC = libc::MADV_NOSYNC,
/// Undoes the effects of [`AdviseFlag::NO_SYNC`] for any future pages
/// dirtied within the address range.
#[cfg(target_os = "freebsd")]
AUTO_SYNC = libc::MADV_AUTOSYNC,
/// Region is not included in a core file.
#[cfg(target_os = "freebsd")]
NO_CORE = libc::MADV_NOCORE,
/// Include region in a core file.
#[cfg(target_os = "freebsd")]
CORE = libc::MADV_CORE,
/// Informs the VM system this process should not be killed when the
/// swap space is exhausted. The process must have superuser privileges.
/// This should be used judiciously in processes that must remain
/// running for the system to properly function.
#[cfg(target_os = "freebsd")]
PROTECT = libc::MADV_PROTECT,
}
);
operation!(
/// [`Future`] behind [`advise`].
pub struct Advise(sys::mem::AdviseOp) -> io::Result<()>;
);
// SAFETY: `!Send` due to address, but the future is `Send`.
#[allow(clippy::non_send_fields_in_send_ty)]
unsafe impl Sync for Advise {}
#[allow(clippy::non_send_fields_in_send_ty)]
unsafe impl Send for Advise {}