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
pub trait GlobalThreadAndCoroutineSwitchableAllocator: Sync + GlobalAlloc + Alloc + Allocator
{
type CoroutineLocalAllocator: LocalAllocator;
type ThreadLocalAllocator: LocalAllocator;
type GlobalAllocator: Allocator;
fn replace_coroutine_local_allocator(&self, replacement: Option<Self::CoroutineLocalAllocator>) -> Option<Self::CoroutineLocalAllocator>;
fn initialize_thread_local_allocator(&self, thread_local_allocator: Self::ThreadLocalAllocator);
fn drop_thread_local_allocator(&self);
fn save_current_allocator_in_use(&self) -> CurrentAllocatorInUse;
fn restore_current_allocator_in_use(&self, restore_to: CurrentAllocatorInUse);
#[inline(always)]
fn callback_with_coroutine_local_allocator<R>(&self, callback: impl FnOnce() -> R) -> R
{
self.callback_with_different_current_allocator(CurrentAllocatorInUse::CoroutineLocal, callback)
}
#[inline(always)]
fn callback_with_thread_local_allocator<R>(&self, callback: impl FnOnce() -> R) -> R
{
self.callback_with_different_current_allocator(CurrentAllocatorInUse::ThreadLocal, callback)
}
#[inline(always)]
fn callback_with_global_allocator<R>(&self, callback: impl FnOnce() -> R) -> R
{
self.callback_with_different_current_allocator(CurrentAllocatorInUse::Global, callback)
}
#[inline(always)]
fn callback_with_different_current_allocator<R>(&self, different: CurrentAllocatorInUse, callback: impl FnOnce() -> R) -> R
{
let restore_to = self.save_current_allocator_in_use();
self.restore_current_allocator_in_use(different);
let result = callback();
self.restore_current_allocator_in_use(restore_to);
result
}
fn coroutine_local_allocator(&self) -> Option<&Self::CoroutineLocalAllocator>;
#[inline(always)]
fn coroutine_local_allocator_unchecked(&self) -> &Self::CoroutineLocalAllocator
{
self.coroutine_local_allocator().expect("Assign the coroutine local allocator first using `replace_coroutine_local_allocator()`")
}
fn thread_local_allocator(&self) -> Option<&Self::ThreadLocalAllocator>;
#[inline(always)]
fn thread_local_allocator_unchecked(&self) -> &Self::ThreadLocalAllocator
{
self.thread_local_allocator().expect("Initialize the thread local allocator first using `initialize_thread_local_allocator()`")
}
fn global_allocator(&self) -> &Self::GlobalAllocator;
}