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
//! Allocation-related traits
//!
//! In order to facilitate operation in many different environments, this crate
//! does not use the `alloc` crate. Instead, it provides a generic interface for
//! specifying your own allocator specifically for boundary tags.
//!
//! With the `nightly` feature, you can use any type that implements
//! [`core::alloc::Allocator`]. Alternatively, you can implement the
//! [`Allocator`] trait yourself if you are able to provide a specialized
//! implementation.
use NonNull;
use crateBt;
/// A generic allocator for boundary tags
///
/// # Implementing
/// In order to implement this trait, you must implement both
/// [`allocate`](Allocator::allocate) and [`deallocate`](Allocator::deallocate).
/// The value returned by these two functions is unspecified, as long as it is a
/// valid allocation of memory that satisfies the size and alignment of a
/// boundary tag. The tag itself may be initialized to any value, and it will be
/// immediately overwritten before use.
///
/// # Bootstrapping
/// Running vmem as the heap allocator is a fairly common use case. However, for
/// this to work, special care must be taken in the [`Allocator`]
/// implementation. The arena will often attempt to allocate boundary tags while
/// it is locked, so it is important to ensure that a bootstrapped allocator
/// does not allocate directly from the arena. Some indirection is necessary. A
/// recommended layout is a slab-style caching allocator. In such an
/// implementation, an allocation would result in the following:
/// 1. If there is space inside the slab, allocate from the slab.
/// 2. If the slab is empty, keep a small emergency cache of boundary tags. Once
/// the allocation is complete (`done` has been called), a new slab can be
/// allocated to restock the emergency cache. Be sure to keep at least 2 tags
/// for this new slab (return `None` 2 elements early).
///
/// A free would simply return the tag to the slab. An allocator may also
/// optionally deallocate slabs, although this is not a necessity, and is not
/// necessarily better for either performance or memory usage.
///
/// In addition, one could choose to return boundary tags to the emergency cache
/// on free if there is a hole. This is not necessary, but may be beneficial.
///
/// If an allocator cannot satisfy an allocation (i.e. the emergency cache is
/// completely empty), it should return `None`. This will be propagated to the
/// caller via [`Error::AllocatorError`](crate::error::Error::AllocatorError)
/// and can be handled there. `done` will not be called in this case.
///
/// # Safety
/// For more advanced safety concerns, this trait follows the same rules as
/// [`core::alloc::Allocator`].
pub unsafe
unsafe