diff options
Diffstat (limited to 'src/libstd/sys/unix/thread.rs')
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 172 |
1 files changed, 96 insertions, 76 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 72b0ac493da..a5b34eeec28 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -25,21 +25,24 @@ unsafe impl Sync for Thread {} // The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc, // so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS. #[cfg(not(target_os = "emscripten"))] -unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t, - stack_size: libc::size_t) -> libc::c_int { +unsafe fn pthread_attr_setstacksize( + attr: *mut libc::pthread_attr_t, + stack_size: libc::size_t, +) -> libc::c_int { libc::pthread_attr_setstacksize(attr, stack_size) } #[cfg(target_os = "emscripten")] -unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t, - _stack_size: libc::size_t) -> libc::c_int { +unsafe fn pthread_attr_setstacksize( + _attr: *mut libc::pthread_attr_t, + _stack_size: libc::size_t, +) -> libc::c_int { panic!() } impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements - pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) - -> io::Result<Thread> { + pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); @@ -47,8 +50,7 @@ impl Thread { let stack_size = cmp::max(stack, min_stack_size(&attr)); - match pthread_attr_setstacksize(&mut attr, - stack_size) { + match pthread_attr_setstacksize(&mut attr, stack_size) { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -57,15 +59,13 @@ impl Thread { // >= PTHREAD_STACK_MIN, it must be an alignment issue. // Round up to the nearest page and try again. let page_size = os::page_size(); - let stack_size = (stack_size + page_size - 1) & - (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, - stack_size), 0); + let stack_size = + (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); + assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); } }; - let ret = libc::pthread_create(&mut native, &attr, thread_start, - &*p as *const _ as *mut _); + let ret = libc::pthread_create(&mut native, &attr, thread_start, &*p as *const _ as *mut _); assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); return if ret != 0 { @@ -75,8 +75,10 @@ impl Thread { Ok(Thread { id: native }) }; - extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { - unsafe { start_thread(main as *mut u8); } + extern "C" fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { + unsafe { + start_thread(main as *mut u8); + } ptr::null_mut() } } @@ -86,8 +88,7 @@ impl Thread { debug_assert_eq!(ret, 0); } - #[cfg(any(target_os = "linux", - target_os = "android"))] + #[cfg(any(target_os = "linux", target_os = "android"))] pub fn set_name(name: &CStr) { const PR_SET_NAME: libc::c_int = 15; // pthread wrapper only appeared in glibc 2.12, so we use syscall @@ -97,9 +98,7 @@ impl Thread { } } - #[cfg(any(target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd"))] + #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))] pub fn set_name(name: &CStr) { unsafe { libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr()); @@ -118,8 +117,11 @@ impl Thread { use crate::ffi::CString; let cname = CString::new(&b"%s"[..]).unwrap(); unsafe { - libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(), - name.as_ptr() as *mut libc::c_void); + libc::pthread_setname_np( + libc::pthread_self(), + cname.as_ptr(), + name.as_ptr() as *mut libc::c_void, + ); } } @@ -132,15 +134,19 @@ impl Thread { } if let Some(f) = pthread_setname_np.get() { - unsafe { f(libc::pthread_self(), name.as_ptr()); } + unsafe { + f(libc::pthread_self(), name.as_ptr()); + } } } - #[cfg(any(target_env = "newlib", - target_os = "haiku", - target_os = "l4re", - target_os = "emscripten", - target_os = "redox"))] + #[cfg(any( + target_env = "newlib", + target_os = "haiku", + target_os = "l4re", + target_os = "emscripten", + target_os = "redox" + ))] pub fn set_name(_name: &CStr) { // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. } @@ -177,12 +183,13 @@ impl Thread { unsafe { let ret = libc::pthread_join(self.id, ptr::null_mut()); mem::forget(self); - assert!(ret == 0, - "failed to join thread: {}", io::Error::from_raw_os_error(ret)); + assert!(ret == 0, "failed to join thread: {}", io::Error::from_raw_os_error(ret)); } } - pub fn id(&self) -> libc::pthread_t { self.id } + pub fn id(&self) -> libc::pthread_t { + self.id + } pub fn into_id(self) -> libc::pthread_t { let id = self.id; @@ -198,31 +205,38 @@ impl Drop for Thread { } } -#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))), - not(target_os = "freebsd"), - not(target_os = "macos"), - not(all(target_os = "netbsd", not(target_vendor = "rumprun"))), - not(target_os = "openbsd"), - not(target_os = "solaris")))] +#[cfg(all( + not(all(target_os = "linux", not(target_env = "musl"))), + not(target_os = "freebsd"), + not(target_os = "macos"), + not(all(target_os = "netbsd", not(target_vendor = "rumprun"))), + not(target_os = "openbsd"), + not(target_os = "solaris") +))] #[cfg_attr(test, allow(dead_code))] pub mod guard { use crate::ops::Range; pub type Guard = Range<usize>; - pub unsafe fn current() -> Option<Guard> { None } - pub unsafe fn init() -> Option<Guard> { None } + pub unsafe fn current() -> Option<Guard> { + None + } + pub unsafe fn init() -> Option<Guard> { + None + } } - -#[cfg(any(all(target_os = "linux", not(target_env = "musl")), - target_os = "freebsd", - target_os = "macos", - all(target_os = "netbsd", not(target_vendor = "rumprun")), - target_os = "openbsd", - target_os = "solaris"))] +#[cfg(any( + all(target_os = "linux", not(target_env = "musl")), + target_os = "freebsd", + target_os = "macos", + all(target_os = "netbsd", not(target_vendor = "rumprun")), + target_os = "openbsd", + target_os = "solaris" +))] #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc::{mmap, mprotect}; - use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; + use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; use crate::ops::Range; use crate::sys::os; @@ -241,16 +255,15 @@ pub mod guard { #[cfg(target_os = "macos")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { - let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize - - libc::pthread_get_stacksize_np(libc::pthread_self()); + let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize + - libc::pthread_get_stacksize_np(libc::pthread_self()); Some(stackaddr as *mut libc::c_void) } #[cfg(target_os = "openbsd")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut current_stack: libc::stack_t = crate::mem::zeroed(); - assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), - &mut current_stack), 0); + assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), &mut current_stack), 0); let stackaddr = if libc::pthread_main_np() == 1 { // main thread @@ -262,21 +275,25 @@ pub mod guard { Some(stackaddr as *mut libc::c_void) } - #[cfg(any(target_os = "android", target_os = "freebsd", - target_os = "linux", target_os = "netbsd", target_os = "l4re"))] + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "l4re" + ))] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let mut ret = None; let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); assert_eq!(libc::pthread_attr_init(&mut attr), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); if e == 0 { let mut stackaddr = crate::ptr::null_mut(); let mut stacksize = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, - &mut stacksize), 0); + assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0); ret = Some(stackaddr); } assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); @@ -329,8 +346,14 @@ pub mod guard { // than the initial mmap() used, so we mmap() here with // read/write permissions and only then mprotect() it to // no permissions at all. See issue #50313. - let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); + let result = mmap( + stackaddr, + PAGE_SIZE, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, + -1, + 0, + ); if result != stackaddr || result == MAP_FAILED { panic!("failed to allocate a guard page"); } @@ -341,34 +364,33 @@ pub mod guard { } let guardaddr = stackaddr as usize; - let offset = if cfg!(target_os = "freebsd") { - 2 - } else { - 1 - }; + let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 }; Some(guardaddr..guardaddr + offset * PAGE_SIZE) } } - #[cfg(any(target_os = "macos", - target_os = "openbsd", - target_os = "solaris"))] + #[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) } - #[cfg(any(target_os = "android", target_os = "freebsd", - target_os = "linux", target_os = "netbsd", target_os = "l4re"))] + #[cfg(any( + target_os = "android", + target_os = "freebsd", + target_os = "linux", + target_os = "netbsd", + target_os = "l4re" + ))] pub unsafe fn current() -> Option<Guard> { let mut ret = None; let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); assert_eq!(libc::pthread_attr_init(&mut attr), 0); #[cfg(target_os = "freebsd")] - let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr); #[cfg(not(target_os = "freebsd"))] - let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); + let e = libc::pthread_getattr_np(libc::pthread_self(), &mut attr); if e == 0 { let mut guardsize = 0; assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0); @@ -377,8 +399,7 @@ pub mod guard { } let mut stackaddr = crate::ptr::null_mut(); let mut size = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, - &mut size), 0); + assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0); let stackaddr = stackaddr as usize; ret = if cfg!(target_os = "freebsd") { @@ -422,8 +443,7 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize { // No point in looking up __pthread_get_minstack() on non-glibc // platforms. -#[cfg(all(not(target_os = "linux"), - not(target_os = "netbsd")))] +#[cfg(all(not(target_os = "linux"), not(target_os = "netbsd")))] fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { libc::PTHREAD_STACK_MIN } |
