global/global.rs
1use rulloc::Rulloc;
2
3// NOTE: This example doesn't work with Miri because we use the global alocator
4// to simulate `mmap` calls when `cfg!(miri)`. If we are the global allocator,
5// there are two problems:
6//
7// 1. We cannot do FFI calls when using Miri, so no `mmap`. That's why we
8// simulate them with `std::alloc::alloc`.
9//
10// 2. The allocator needs to acquire a `Mutex` lock in order to modify its
11// structures. Whenever somebody calls `allocate` on our allocator (for example
12// `Box`) the calling thread will acquire the lock. However, when the thread
13// calls `mmap` to obtain a new region, `std::alloc::alloc` will be called
14// instead, but WE are the allocator, so we'll try to acquire the lock again,
15// which causes a deadlock. It turns out that we cannot simulate ourselves
16// within ourselves :(
17
18#[global_allocator]
19static ALLOCATOR: Rulloc = Rulloc::with_default_config();
20
21fn main() {
22 let num = Box::new(10);
23 println!("Boxed num {num} at {:?}", &*num as *const usize);
24
25 let mut vec = Vec::with_capacity(*num);
26
27 for i in 0..*num {
28 vec.push(i);
29 }
30
31 println!("Vec: {vec:?} at {:?}", vec.as_ptr());
32
33 let handle = std::thread::spawn(|| {
34 let mut vec: Vec<u8> = Vec::with_capacity(256);
35 vec.push(5);
36 vec.push(6);
37 println!("Second thread Vec: {vec:?} at {:?}", vec.as_ptr());
38 });
39
40 handle.join().unwrap();
41
42 let cap = 1024 * 1024;
43 let mut vec: Vec<u8> = Vec::with_capacity(cap);
44 vec.push(1);
45
46 println!("Large allocation of {cap} bytes at {:?}", vec.as_ptr());
47}