2015-04-16 20:06:57 +08:00
|
|
|
// This file is part of libfringe, a low-level green threading library.
|
2015-04-16 18:08:44 +08:00
|
|
|
// Copyright (c) 2015, edef <edef@edef.eu>
|
|
|
|
// See the LICENSE file included in this distribution.
|
2015-04-16 14:04:06 +08:00
|
|
|
extern crate libc;
|
2015-04-16 17:14:09 +08:00
|
|
|
use self::libc::{c_void, c_int, size_t};
|
|
|
|
use self::libc::{mmap, mprotect, munmap};
|
|
|
|
use self::libc::MAP_FAILED;
|
2015-04-16 17:50:54 +08:00
|
|
|
use super::page_size;
|
2015-04-16 14:04:06 +08:00
|
|
|
|
|
|
|
use core::ptr;
|
|
|
|
|
2015-04-16 17:50:54 +08:00
|
|
|
#[cold]
|
|
|
|
pub fn sys_page_size() -> usize {
|
2015-04-16 14:04:06 +08:00
|
|
|
unsafe {
|
|
|
|
libc::sysconf(libc::_SC_PAGESIZE) as usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-16 17:14:09 +08:00
|
|
|
const GUARD_PROT: c_int = libc::PROT_NONE;
|
|
|
|
const STACK_PROT: c_int = libc::PROT_READ
|
|
|
|
| libc::PROT_WRITE;
|
2015-04-16 19:56:26 +08:00
|
|
|
#[cfg(not(any(target_os = "freebsd", target_os = "dragonfly")))]
|
2015-04-16 17:14:09 +08:00
|
|
|
const STACK_FLAGS: c_int = libc::MAP_STACK
|
|
|
|
| libc::MAP_PRIVATE
|
|
|
|
| libc::MAP_ANON;
|
2015-04-16 19:56:26 +08:00
|
|
|
// workaround for http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
|
|
|
|
// according to libgreen, DragonFlyBSD suffers from this too
|
|
|
|
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
|
|
|
const STACK_FLAGS: c_int = libc::MAP_PRIVATE
|
|
|
|
| libc::MAP_ANON;
|
2015-04-16 14:04:06 +08:00
|
|
|
|
|
|
|
pub unsafe fn map_stack(len: usize) -> Option<*mut u8> {
|
|
|
|
let ptr = mmap(ptr::null_mut(), len as size_t,
|
|
|
|
STACK_PROT, STACK_FLAGS, -1, 0);
|
2016-03-16 07:20:45 +08:00
|
|
|
if ptr == MAP_FAILED {
|
2015-04-16 14:04:06 +08:00
|
|
|
None
|
2016-03-16 07:20:45 +08:00
|
|
|
} else {
|
|
|
|
Some(ptr as *mut u8)
|
2015-04-16 14:04:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn protect_stack(ptr: *mut u8) -> bool {
|
|
|
|
mprotect(ptr as *mut c_void, page_size() as size_t, GUARD_PROT) == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn unmap_stack(ptr: *mut u8, len: usize) -> bool {
|
|
|
|
munmap(ptr as *mut c_void, len as size_t) == 0
|
|
|
|
}
|