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
use NonNull;
use cratemock;
use craterelease_reservation;
use cratePAGE;
use crateReservationParts;
/// Release a whole OS reservation obtained from [`Reservation::into_parts`](crate::Reservation::into_parts).
///
/// # Safety
///
/// `reservation`, `reservation_len` and `align` must be the three values
/// returned by [`Reservation::into_parts`](crate::Reservation::into_parts) (or, for a self-hosting caller that
/// always uses one alignment, that same alignment constant), and the
/// reservation must be released **exactly once**. The native (`munmap` /
/// `VirtualFree`) paths ignore `align`; it is consulted only by the miri
/// fallback to reconstruct the exact `Layout`.
///
/// If `reservation` is null, this function returns early and does nothing
/// (the call is a no-op). The mock recorder is also skipped in this case,
/// so a `mock`-based test's expected call log may desync if it expects a
/// record for a null pointer.
///
/// # Panics
///
/// Panics if `reservation` is non-null and `(reservation_len, align)` violates
/// the documented contract above: `reservation_len` must be non-zero and a
/// multiple of [`PAGE`], `align` must be a power of two `>= PAGE`, and the
/// pair must form a valid [`std::alloc::Layout`]. The assert runs before
/// `mock::record`, so under the `aligned_vmem_mock` cfg a contract-violating
/// call panics before it is ever recorded in the mock call log — it does not
/// appear as a `Release` entry.
///
/// A null `reservation` is unaffected by this: it remains the documented
/// no-op above and is not a panic path.
pub unsafe
/// Release a reservation obtained from [`Reservation::into_reservation_parts`](crate::Reservation::into_reservation_parts).
///
/// This is the typed alternative to [`release`]: it takes a [`ReservationParts`]
/// struct instead of raw parameters, preventing accidental swapping of `len` and
/// `align` (which would cause undefined behavior on the native backend and leaks
/// or crashes on Unix).
///
/// For backwards compatibility with code that uses the raw tuple form, you can
/// convert a `ReservationParts` to a tuple via [`ReservationParts::as_tuple`] and
/// call [`release`].
///
/// # Safety
///
/// `parts.ptr` must be a reservation obtained from [`Reservation::into_reservation_parts`](crate::Reservation::into_reservation_parts)
/// (or the raw [`Reservation::into_parts`](crate::Reservation::into_parts)) and must be live. The reservation must be released
/// exactly once.
pub unsafe