Skip to content

Commit

Permalink
libstd: remove some mutable statics in sys::unix
Browse files Browse the repository at this point in the history
  • Loading branch information
euclio committed Jul 7, 2020
1 parent f844ea1 commit 792f2de
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 26 deletions.
19 changes: 11 additions & 8 deletions src/libstd/sys/unix/args.rs
Expand Up @@ -78,19 +78,20 @@ mod imp {
use crate::marker::PhantomData;
use crate::os::unix::prelude::*;
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};

use crate::sys_common::mutex::Mutex;

static mut ARGC: isize = 0;
static mut ARGV: *const *const u8 = ptr::null();
static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
// acquire this mutex reentrantly!
static LOCK: Mutex = Mutex::new();

unsafe fn really_init(argc: isize, argv: *const *const u8) {
let _guard = LOCK.lock();
ARGC = argc;
ARGV = argv;
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}

#[inline(always)]
Expand Down Expand Up @@ -126,8 +127,8 @@ mod imp {

pub unsafe fn cleanup() {
let _guard = LOCK.lock();
ARGC = 0;
ARGV = ptr::null();
ARGC.store(0, Ordering::Relaxed);
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
}

pub fn args() -> Args {
Expand All @@ -137,9 +138,11 @@ mod imp {
fn clone() -> Vec<OsString> {
unsafe {
let _guard = LOCK.lock();
(0..ARGC)
let argc = ARGC.load(Ordering::Relaxed);
let argv = ARGV.load(Ordering::Relaxed);
(0..argc)
.map(|i| {
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
OsStringExt::from_vec(cstr.to_bytes().to_vec())
})
.collect()
Expand Down
13 changes: 7 additions & 6 deletions src/libstd/sys/unix/stack_overflow.rs
Expand Up @@ -48,6 +48,7 @@ mod imp {
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};

use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use crate::sys::unix::os::page_size;
use crate::sys_common::thread_info;

Expand Down Expand Up @@ -113,8 +114,8 @@ mod imp {
}
}

static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
static mut NEED_ALTSTACK: bool = false;
static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);

pub unsafe fn init() {
let mut action: sigaction = mem::zeroed();
Expand All @@ -125,17 +126,17 @@ mod imp {
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
action.sa_sigaction = signal_handler as sighandler_t;
sigaction(signal, &action, ptr::null_mut());
NEED_ALTSTACK = true;
NEED_ALTSTACK.store(true, Ordering::Relaxed);
}
}

let handler = make_handler();
MAIN_ALTSTACK = handler._data;
MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed);
mem::forget(handler);
}

pub unsafe fn cleanup() {
Handler { _data: MAIN_ALTSTACK };
Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) };
}

unsafe fn get_stackp() -> *mut libc::c_void {
Expand Down Expand Up @@ -176,7 +177,7 @@ mod imp {
}

pub unsafe fn make_handler() -> Handler {
if !NEED_ALTSTACK {
if !NEED_ALTSTACK.load(Ordering::Relaxed) {
return Handler::null();
}
let mut stack = mem::zeroed();
Expand Down
27 changes: 15 additions & 12 deletions src/libstd/sys/unix/thread.rs
Expand Up @@ -246,10 +246,11 @@ pub mod guard {
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};

use crate::ops::Range;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os;

// This is initialized in init() and only read from after
static mut PAGE_SIZE: usize = 0;
static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);

pub type Guard = Range<usize>;

Expand All @@ -275,7 +276,7 @@ pub mod guard {

let stackaddr = if libc::pthread_main_np() == 1 {
// main thread
current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE
current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed)
} else {
// new thread
current_stack.ss_sp as usize - current_stack.ss_size
Expand Down Expand Up @@ -310,7 +311,8 @@ pub mod guard {

// Precondition: PAGE_SIZE is initialized.
unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
assert!(PAGE_SIZE != 0);
let page_size = PAGE_SIZE.load(Ordering::Relaxed);
assert!(page_size != 0);
let stackaddr = get_stack_start()?;

// Ensure stackaddr is page aligned! A parent process might
Expand All @@ -319,16 +321,17 @@ pub mod guard {
// stackaddr < stackaddr + stacksize, so if stackaddr is not
// page-aligned, calculate the fix such that stackaddr <
// new_page_aligned_stackaddr < stackaddr + stacksize
let remainder = (stackaddr as usize) % PAGE_SIZE;
let remainder = (stackaddr as usize) % page_size;
Some(if remainder == 0 {
stackaddr
} else {
((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
((stackaddr as usize) + page_size - remainder) as *mut libc::c_void
})
}

pub unsafe fn init() -> Option<Guard> {
PAGE_SIZE = os::page_size();
let page_size = os::page_size();
PAGE_SIZE.store(page_size, Ordering::Relaxed);

let stackaddr = get_stack_start_aligned()?;

Expand All @@ -344,7 +347,7 @@ pub mod guard {
// faulting, so our handler can report "stack overflow", and
// trust that the kernel's own stack guard will work.
let stackaddr = stackaddr as usize;
Some(stackaddr - PAGE_SIZE..stackaddr)
Some(stackaddr - page_size..stackaddr)
} else {
// Reallocate the last page of the stack.
// This ensures SIGBUS will be raised on
Expand All @@ -356,7 +359,7 @@ pub mod guard {
// no permissions at all. See issue #50313.
let result = mmap(
stackaddr,
PAGE_SIZE,
page_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-1,
Expand All @@ -366,22 +369,22 @@ pub mod guard {
panic!("failed to allocate a guard page");
}

let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
let result = mprotect(stackaddr, page_size, PROT_NONE);
if result != 0 {
panic!("failed to protect the guard page");
}

let guardaddr = stackaddr as usize;
let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 };

Some(guardaddr..guardaddr + offset * PAGE_SIZE)
Some(guardaddr..guardaddr + offset * page_size)
}
}

#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
pub unsafe fn current() -> Option<Guard> {
let stackaddr = get_stack_start()? as usize;
Some(stackaddr - PAGE_SIZE..stackaddr)
Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr)
}

#[cfg(any(
Expand Down Expand Up @@ -413,7 +416,7 @@ pub mod guard {
ret = if cfg!(target_os = "freebsd") {
// FIXME does freebsd really fault *below* the guard addr?
let guardaddr = stackaddr - guardsize;
Some(guardaddr - PAGE_SIZE..guardaddr)
Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
} else if cfg!(target_os = "netbsd") {
Some(stackaddr - guardsize..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "gnu")) {
Expand Down

0 comments on commit 792f2de

Please sign in to comment.