Skip to content

Commit

Permalink
Use smallvec for dtor lists. (#93)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sunfishcode authored Nov 9, 2023
1 parent 42c8cad commit 53be46b
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ errno = { version = "0.3.3", default-features = false, optional = true }
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
compiler_builtins = { version = "0.1.101", optional = true }
smallvec = { version = "1.11.1", features = ["const_new"] }

[target.'cfg(not(target_arch = "arm"))'.dependencies.unwinding]
version = "0.2.0"
Expand Down
10 changes: 7 additions & 3 deletions src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
use crate::thread::{initialize_main_thread, initialize_startup_thread_info};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(all(feature = "alloc", feature = "origin-program"))]
use alloc::vec::Vec;
#[cfg(not(feature = "origin-program"))]
use core::ptr::null_mut;
use linux_raw_sys::ctypes::c_int;
Expand Down Expand Up @@ -219,8 +217,14 @@ unsafe fn init_runtime(mem: *mut usize, envp: *mut *mut u8) {
}

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

/// Register a function to be called when [`exit`] is called.
///
Expand Down
7 changes: 4 additions & 3 deletions src/thread/linux_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use crate::arch::{clone, munmap_and_exit_thread, set_thread_pointer, thread_pointer, TLS_OFFSET};
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::any::Any;
use core::cmp::max;
use core::ffi::c_void;
Expand Down Expand Up @@ -63,7 +62,9 @@ struct ThreadData {
stack_size: usize,
guard_size: usize,
map_size: usize,
dtors: Vec<Box<dyn FnOnce()>>,

// Support a few dtors before using dynamic allocation.
dtors: smallvec::SmallVec<[Box<dyn FnOnce()>; 4]>,
}

// Values for `ThreadData::detached`.
Expand All @@ -87,7 +88,7 @@ impl ThreadData {
stack_size,
guard_size,
map_size,
dtors: Vec::new(),
dtors: smallvec::SmallVec::new(),
}
}
}
Expand Down

0 comments on commit 53be46b

Please sign in to comment.