about summary refs log tree commit diff
path: root/src/libstd/sys/unix/thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys/unix/thread.rs')
-rw-r--r--src/libstd/sys/unix/thread.rs27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 7b3d69dcaa0..c1bda6b430e 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -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>;
 
@@ -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
@@ -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
@@ -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()?;
 
@@ -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
@@ -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,
@@ -366,7 +369,7 @@ 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");
             }
@@ -374,14 +377,14 @@ pub mod guard {
             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(
@@ -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")) {