From 0d7b3d7091f231ad977a3a1bd1f7ad5f93d5fcb3 Mon Sep 17 00:00:00 2001 From: edef Date: Thu, 14 Apr 2016 15:49:37 +0200 Subject: [PATCH] add Windows support to OsStack Fix #18 --- Cargo.toml | 10 +++++++++- src/os/sys/mod.rs | 4 ++++ src/os/sys/windows.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/os/sys/windows.rs diff --git a/Cargo.toml b/Cargo.toml index 8ab13c8..3f79363 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,10 @@ authors = ["edef "] name = "fringe" version = "0.0.1" +[dependencies.kernel32-sys] +optional = true +version = "0.2.2" + [dependencies.libc] optional = true version = "0.1.6" @@ -16,6 +20,10 @@ rev = "9ef793e9549aabfd2d969615180b69d29ce28d88" default-features = false version = "1" +[dependencies.winapi] +optional = true +version = "0.2.6" + [features] default = ["os", "valgrind"] -os = ["libc"] +os = ["libc", "kernel32-sys", "winapi"] diff --git a/src/os/sys/mod.rs b/src/os/sys/mod.rs index 57edbc2..07aa4f4 100644 --- a/src/os/sys/mod.rs +++ b/src/os/sys/mod.rs @@ -10,6 +10,10 @@ use self::imp::sys_page_size; #[path = "unix.rs"] mod imp; +#[cfg(windows)] +#[path = "windows.rs"] +mod imp; + static PAGE_SIZE_CACHE: AtomicUsize = ATOMIC_USIZE_INIT; pub fn page_size() -> usize { match PAGE_SIZE_CACHE.load(Ordering::Relaxed) { diff --git a/src/os/sys/windows.rs b/src/os/sys/windows.rs new file mode 100644 index 0000000..eb289a7 --- /dev/null +++ b/src/os/sys/windows.rs @@ -0,0 +1,37 @@ +// This file is part of libfringe, a low-level green threading library. +// Copyright (c) edef +// See the LICENSE file included in this distribution. +extern crate winapi; +extern crate kernel32; +use core::{mem, ptr}; +use self::winapi::basetsd::SIZE_T; +use self::winapi::minwindef::{DWORD, LPVOID}; +use self::winapi::winnt::{MEM_COMMIT, MEM_RESERVE, MEM_RELEASE, PAGE_READWRITE, PAGE_NOACCESS}; +use super::page_size; + +#[cfg(windows)] +pub fn sys_page_size() -> usize { + unsafe { + let mut info = mem::zeroed(); + kernel32::GetSystemInfo(&mut info); + info.dwPageSize as usize + } +} + +pub unsafe fn map_stack(len: usize) -> Option<*mut u8> { + let ptr = kernel32::VirtualAlloc(ptr::null_mut(), len as SIZE_T, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if ptr == ptr::null_mut() { + None + } else { + Some(ptr as *mut u8) + } +} + +pub unsafe fn protect_stack(ptr: *mut u8) -> bool { + let mut old_prot: DWORD = 0; + kernel32::VirtualProtect(ptr as LPVOID, page_size() as SIZE_T, PAGE_NOACCESS, &mut old_prot) != 0 +} + +pub unsafe fn unmap_stack(ptr: *mut u8, _len: usize) -> bool { + kernel32::VirtualFree(ptr as LPVOID, 0, MEM_RELEASE) != 0 +}