Skip to content

Commit 8ac1525

Browse files
committed
Auto merge of #74006 - euclio:sys-unix-static-mut, r=oli-obk
libstd: remove some mutable statics in sys::unix My understanding is that this achieves the same behavior and performance with safe code.
2 parents e1beee4 + 792f2de commit 8ac1525

File tree

3 files changed

+33
-26
lines changed

3 files changed

+33
-26
lines changed

src/libstd/sys/unix/args.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,20 @@ mod imp {
7878
use crate::marker::PhantomData;
7979
use crate::os::unix::prelude::*;
8080
use crate::ptr;
81+
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
8182

8283
use crate::sys_common::mutex::Mutex;
8384

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

9091
unsafe fn really_init(argc: isize, argv: *const *const u8) {
9192
let _guard = LOCK.lock();
92-
ARGC = argc;
93-
ARGV = argv;
93+
ARGC.store(argc, Ordering::Relaxed);
94+
ARGV.store(argv as *mut _, Ordering::Relaxed);
9495
}
9596

9697
#[inline(always)]
@@ -126,8 +127,8 @@ mod imp {
126127

127128
pub unsafe fn cleanup() {
128129
let _guard = LOCK.lock();
129-
ARGC = 0;
130-
ARGV = ptr::null();
130+
ARGC.store(0, Ordering::Relaxed);
131+
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
131132
}
132133

133134
pub fn args() -> Args {
@@ -137,9 +138,11 @@ mod imp {
137138
fn clone() -> Vec<OsString> {
138139
unsafe {
139140
let _guard = LOCK.lock();
140-
(0..ARGC)
141+
let argc = ARGC.load(Ordering::Relaxed);
142+
let argv = ARGV.load(Ordering::Relaxed);
143+
(0..argc)
141144
.map(|i| {
142-
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
145+
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
143146
OsStringExt::from_vec(cstr.to_bytes().to_vec())
144147
})
145148
.collect()

src/libstd/sys/unix/stack_overflow.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ mod imp {
4848
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
4949
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
5050

51+
use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
5152
use crate::sys::unix::os::page_size;
5253
use crate::sys_common::thread_info;
5354

@@ -113,8 +114,8 @@ mod imp {
113114
}
114115
}
115116

116-
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
117-
static mut NEED_ALTSTACK: bool = false;
117+
static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
118+
static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);
118119

119120
pub unsafe fn init() {
120121
let mut action: sigaction = mem::zeroed();
@@ -125,17 +126,17 @@ mod imp {
125126
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
126127
action.sa_sigaction = signal_handler as sighandler_t;
127128
sigaction(signal, &action, ptr::null_mut());
128-
NEED_ALTSTACK = true;
129+
NEED_ALTSTACK.store(true, Ordering::Relaxed);
129130
}
130131
}
131132

132133
let handler = make_handler();
133-
MAIN_ALTSTACK = handler._data;
134+
MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed);
134135
mem::forget(handler);
135136
}
136137

137138
pub unsafe fn cleanup() {
138-
Handler { _data: MAIN_ALTSTACK };
139+
Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) };
139140
}
140141

141142
unsafe fn get_stackp() -> *mut libc::c_void {
@@ -176,7 +177,7 @@ mod imp {
176177
}
177178

178179
pub unsafe fn make_handler() -> Handler {
179-
if !NEED_ALTSTACK {
180+
if !NEED_ALTSTACK.load(Ordering::Relaxed) {
180181
return Handler::null();
181182
}
182183
let mut stack = mem::zeroed();

src/libstd/sys/unix/thread.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,11 @@ pub mod guard {
246246
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
247247

248248
use crate::ops::Range;
249+
use crate::sync::atomic::{AtomicUsize, Ordering};
249250
use crate::sys::os;
250251

251252
// This is initialized in init() and only read from after
252-
static mut PAGE_SIZE: usize = 0;
253+
static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
253254

254255
pub type Guard = Range<usize>;
255256

@@ -275,7 +276,7 @@ pub mod guard {
275276

276277
let stackaddr = if libc::pthread_main_np() == 1 {
277278
// main thread
278-
current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE
279+
current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed)
279280
} else {
280281
// new thread
281282
current_stack.ss_sp as usize - current_stack.ss_size
@@ -310,7 +311,8 @@ pub mod guard {
310311

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

316318
// Ensure stackaddr is page aligned! A parent process might
@@ -319,16 +321,17 @@ pub mod guard {
319321
// stackaddr < stackaddr + stacksize, so if stackaddr is not
320322
// page-aligned, calculate the fix such that stackaddr <
321323
// new_page_aligned_stackaddr < stackaddr + stacksize
322-
let remainder = (stackaddr as usize) % PAGE_SIZE;
324+
let remainder = (stackaddr as usize) % page_size;
323325
Some(if remainder == 0 {
324326
stackaddr
325327
} else {
326-
((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
328+
((stackaddr as usize) + page_size - remainder) as *mut libc::c_void
327329
})
328330
}
329331

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

333336
let stackaddr = get_stack_start_aligned()?;
334337

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

369-
let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
372+
let result = mprotect(stackaddr, page_size, PROT_NONE);
370373
if result != 0 {
371374
panic!("failed to protect the guard page");
372375
}
373376

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

377-
Some(guardaddr..guardaddr + offset * PAGE_SIZE)
380+
Some(guardaddr..guardaddr + offset * page_size)
378381
}
379382
}
380383

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

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

0 commit comments

Comments
 (0)