Skip to content

Commit

Permalink
Rollup merge of #87236 - sunfishcode:avoid-locking-args, r=joshtriplett
Browse files Browse the repository at this point in the history
Simplify command-line argument initialization on unix

Simplify Rust's command-line argument initialization code on unix:
 - The cleanup code isn't needed, because it was just zeroing out non-owning variables at runtime cleanup time. After 91c3eee, Rust's command-line initialization code on unix no longer allocates `CString`s and a `Vec` at startup time.
 - The `Mutex` isn't needed; if there's somehow a call to `args()` before argument initialization has happened, the code returns return an empty list, which we can do with a null check.

With these changes, a simple cdylib that doesn't use threads avoids getting `pthread_mutex_lock`/`pthread_mutex_unlock` in its symbol table.
  • Loading branch information
GuillaumeGomez authored Jul 19, 2021
2 parents 65b7aa9 + c3df0ae commit 6df9df7
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 22 deletions.
24 changes: 3 additions & 21 deletions library/std/src/sys/unix/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
imp::init(argc, argv)
}

/// One-time global cleanup.
pub unsafe fn cleanup() {
imp::cleanup()
}

/// Returns the command line arguments
pub fn args() -> Args {
imp::args()
Expand Down Expand Up @@ -82,16 +77,10 @@ mod imp {
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};

use crate::sys_common::mutex::StaticMutex;

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: StaticMutex = StaticMutex::new();

unsafe fn really_init(argc: isize, argv: *const *const u8) {
let _guard = LOCK.lock();
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}
Expand Down Expand Up @@ -127,21 +116,16 @@ mod imp {
init_wrapper
};

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

pub fn args() -> Args {
Args { iter: clone().into_iter() }
}

fn clone() -> Vec<OsString> {
unsafe {
let _guard = LOCK.lock();
let argc = ARGC.load(Ordering::Relaxed);
// Load ARGC and ARGV without a lock. If the store to either ARGV or
// ARGC isn't visible yet, we'll return an empty argument list.
let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc)
.map(|i| {
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
Expand All @@ -159,8 +143,6 @@ mod imp {

pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}

pub fn cleanup() {}

#[cfg(target_os = "macos")]
pub fn args() -> Args {
use crate::os::unix::prelude::*;
Expand Down
1 change: 0 additions & 1 deletion library/std/src/sys/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {
args::cleanup();
stack_overflow::cleanup();
}

Expand Down

0 comments on commit 6df9df7

Please sign in to comment.