Skip to content

Commit 53be46b

Browse files
authored
Use smallvec for dtor lists. (#93)
Use `smallvec` for `at_exit` and `at_thread_exit` dtor lists. This helps us follow the POSIX rule that at least 32 functions be registerable, and helps origin run in settings where thread destructors are registered from within a malloc implementation.
1 parent 42c8cad commit 53be46b

File tree

3 files changed

+12
-6
lines changed

3 files changed

+12
-6
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ errno = { version = "0.3.3", default-features = false, optional = true }
4040
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
4141
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
4242
compiler_builtins = { version = "0.1.101", optional = true }
43+
smallvec = { version = "1.11.1", features = ["const_new"] }
4344

4445
[target.'cfg(not(target_arch = "arm"))'.dependencies.unwinding]
4546
version = "0.2.0"

src/program.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
use crate::thread::{initialize_main_thread, initialize_startup_thread_info};
3232
#[cfg(feature = "alloc")]
3333
use alloc::boxed::Box;
34-
#[cfg(all(feature = "alloc", feature = "origin-program"))]
35-
use alloc::vec::Vec;
3634
#[cfg(not(feature = "origin-program"))]
3735
use core::ptr::null_mut;
3836
use linux_raw_sys::ctypes::c_int;
@@ -219,8 +217,14 @@ unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) {
219217
}
220218

221219
/// Functions registered with [`at_exit`].
220+
///
221+
/// [POSIX guarantees] at least 32 handlers can be registered, so use a
222+
/// `SmallVec` to ensure we can register that many without allocating.
223+
///
224+
/// [POSIX guarantees]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/atexit.html
222225
#[cfg(all(feature = "alloc", feature = "origin-program"))]
223-
static DTORS: Mutex<Vec<Box<dyn FnOnce() + Send>>> = Mutex::new(Vec::new());
226+
static DTORS: Mutex<smallvec::SmallVec<[Box<dyn FnOnce() + Send>; 32]>> =
227+
Mutex::new(smallvec::SmallVec::new_const());
224228

225229
/// Register a function to be called when [`exit`] is called.
226230
///

src/thread/linux_raw.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use crate::arch::{clone, munmap_and_exit_thread, set_thread_pointer, thread_pointer, TLS_OFFSET};
44
use alloc::boxed::Box;
5-
use alloc::vec::Vec;
65
use core::any::Any;
76
use core::cmp::max;
87
use core::ffi::c_void;
@@ -63,7 +62,9 @@ struct ThreadData {
6362
stack_size: usize,
6463
guard_size: usize,
6564
map_size: usize,
66-
dtors: Vec<Box<dyn FnOnce()>>,
65+
66+
// Support a few dtors before using dynamic allocation.
67+
dtors: smallvec::SmallVec<[Box<dyn FnOnce()>; 4]>,
6768
}
6869

6970
// Values for `ThreadData::detached`.
@@ -87,7 +88,7 @@ impl ThreadData {
8788
stack_size,
8889
guard_size,
8990
map_size,
90-
dtors: Vec::new(),
91+
dtors: smallvec::SmallVec::new(),
9192
}
9293
}
9394
}

0 commit comments

Comments
 (0)