Skip to content

Commit

Permalink
Merge #31
Browse files Browse the repository at this point in the history
31: Register new threads with the collector r=ltratt a=jacob-hughes



Co-authored-by: Jake Hughes <jh@jakehughes.uk>
  • Loading branch information
bors[bot] and jacob-hughes authored Apr 9, 2021
2 parents e62b302 + 94b0ef8 commit 689c3c2
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .buildbot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ set -e
# Ensure the build fails if it uses excessive amounts of memory.
ulimit -d $((1024 * 1024 * 8)) # 8 GiB

./x.py test --stage 1 --exclude rustdoc-json
./x.py test --stage 1 --exclude rustdoc-json --exclude debuginfo
9 changes: 9 additions & 0 deletions library/std/src/rt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn lang_start_internal(
argc: isize,
argv: *const *const u8,
) -> isize {
use crate::alloc::GcAllocator;
use crate::panic;
use crate::sys;
use crate::sys_common;
Expand All @@ -34,6 +35,14 @@ fn lang_start_internal(
sys::init();

unsafe {
// Internally, this registers a SIGSEGV handler to compute the start and
// end bounds of the data segment. This means it *MUST* be called before
// rustc registers its own SIGSEGV stack overflow handler.
//
// Rust's stack overflow handler will unregister and return if there is
// no stack overflow, allowing the fault to "fall-through" to Boehm's
// handler next time. The is not true in the reverse case.
GcAllocator::init();
let main_guard = sys::thread::guard::init();
sys::stack_overflow::init();

Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ pub mod guard {
target_os = "netbsd",
target_os = "l4re"
))]
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
pub(crate) unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
let mut ret = None;
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
#[cfg(target_os = "freebsd")]
Expand Down
16 changes: 16 additions & 0 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;

use crate::alloc::GcAllocator;
use crate::any::Any;
use crate::cell::UnsafeCell;
use crate::ffi::{CStr, CString};
Expand Down Expand Up @@ -464,6 +465,15 @@ impl Builder {
imp::Thread::set_name(name);
}

// SAFETY: Register the thread with libgc so that its stack can be scanned
// for garbage collection.
let stack_start = unsafe { imp::guard::get_stack_start().unwrap() };
if stack_start != crate::ptr::null_mut() {
unsafe {
GcAllocator::register_thread(&stack_start as *const _ as *mut u8);
}
}

crate::io::set_output_capture(output_capture);

// SAFETY: the stack guard passed is the one for the current thread.
Expand All @@ -473,6 +483,12 @@ impl Builder {
let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
}));

// SAFETY: The thread has no more work to do, so can be unregisterd.
unsafe {
GcAllocator::unregister_thread();
}

// SAFETY: `their_packet` as been built just above and moved by the
// closure (it is an Arc<...>) and `my_packet` will be stored in the
// same `JoinInner` as this closure meaning the mutation will be
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/threads-sendsync/thread_registration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// run-pass
// ignore-emscripten no threads support
#![feature(rustc_private)]

use std::alloc::GcAllocator;
use std::thread;

pub fn main() {
let res = thread::spawn(child).join().unwrap();
assert!(res);
}

fn child() -> bool {
GcAllocator::thread_registered()
}

0 comments on commit 689c3c2

Please sign in to comment.