stacker/backends/
unix.rs

1#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "illumos"))]
2use libc::pthread_attr_get_np as get_attr;
3#[cfg(any(target_os = "linux", target_os = "solaris", target_os = "netbsd"))]
4use libc::pthread_getattr_np as get_attr;
5
6pub unsafe fn guess_os_stack_limit() -> Option<usize> {
7    let mut attr = PthreadAttr::new()?;
8    (get_attr(libc::pthread_self(), &mut attr.0) == 0).then_some(())?;
9    let mut stackaddr = std::ptr::null_mut();
10    let mut stacksize = 0;
11    (libc::pthread_attr_getstack(&attr.0, &mut stackaddr, &mut stacksize) == 0).then_some(())?;
12    Some(stackaddr as usize)
13}
14
15struct PthreadAttr(libc::pthread_attr_t);
16
17impl Drop for PthreadAttr {
18    fn drop(&mut self) {
19        unsafe {
20            let ret = libc::pthread_attr_destroy(&mut self.0);
21            if ret != 0 {
22                let err = std::io::Error::last_os_error();
23                panic!(
24                    "pthread_attr_destroy failed with error code {}: {}",
25                    ret, err
26                );
27            }
28        }
29    }
30}
31
32impl PthreadAttr {
33    unsafe fn new() -> Option<Self> {
34        let mut attr = std::mem::MaybeUninit::<libc::pthread_attr_t>::uninit();
35        if libc::pthread_attr_init(attr.as_mut_ptr()) != 0 {
36            return None;
37        }
38        Some(PthreadAttr(attr.assume_init()))
39    }
40}