about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorCorey Richardson <corey@octayn.net>2013-11-13 05:21:38 -0500
committerAlex Crichton <alex@alexcrichton.com>2014-01-24 22:30:00 -0800
commitdee7fa58dd4203a19b83ad47c3b0a0efb92c0e9a (patch)
treeadb1ec1b8219633b3a7d65611cd2a1648d658f61 /src/libstd
parent462f09e9494481456b22630cb42a3c0544a08625 (diff)
downloadrust-dee7fa58dd4203a19b83ad47c3b0a0efb92c0e9a.tar.gz
rust-dee7fa58dd4203a19b83ad47c3b0a0efb92c0e9a.zip
Use `mmap` to map in task stacks and guard page
Also implement caching of stacks.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/libc.rs1
-rw-r--r--src/libstd/os.rs49
-rw-r--r--src/libstd/rt/env.rs15
3 files changed, 41 insertions, 24 deletions
diff --git a/src/libstd/libc.rs b/src/libstd/libc.rs
index a398835824b..d5f185880fa 100644
--- a/src/libstd/libc.rs
+++ b/src/libstd/libc.rs
@@ -2863,6 +2863,7 @@ pub mod consts {
             pub static MAP_PRIVATE : c_int = 0x0002;
             pub static MAP_FIXED : c_int = 0x0010;
             pub static MAP_ANON : c_int = 0x1000;
+            pub static MAP_STACK : c_int = 0;
 
             pub static MAP_FAILED : *c_void = -1 as *c_void;
 
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index cdf0c3b6442..b594b91d2dc 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -39,7 +39,7 @@ use os;
 use prelude::*;
 use ptr;
 use str;
-use to_str;
+use fmt;
 use unstable::finally::Finally;
 use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 
@@ -871,7 +871,7 @@ pub enum MapOption {
     MapOffset(uint),
     /// On POSIX, this can be used to specify the default flags passed to `mmap`. By default it uses
     /// `MAP_PRIVATE` and, if not using `MapFd`, `MAP_ANON`. This will override both of those. This
-    /// is platform-specific (the exact values used) and unused on Windows.
+    /// is platform-specific (the exact values used) and ignored on Windows.
     MapNonStandardFlags(c_int),
 }
 
@@ -911,23 +911,29 @@ pub enum MapError {
     ErrMapViewOfFile(uint)
 }
 
-impl to_str::ToStr for MapError {
-    fn to_str(&self) -> ~str {
-        match *self {
-            ErrFdNotAvail => ~"fd not available for reading or writing",
-            ErrInvalidFd => ~"Invalid fd",
-            ErrUnaligned => ~"Unaligned address, invalid flags, \
-                              negative length or unaligned offset",
-            ErrNoMapSupport=> ~"File doesn't support mapping",
-            ErrNoMem => ~"Invalid address, or not enough available memory",
-            ErrUnknown(code) => format!("Unknown error={}", code),
-            ErrUnsupProt => ~"Protection mode unsupported",
-            ErrUnsupOffset => ~"Offset in virtual memory mode is unsupported",
-            ErrAlreadyExists => ~"File mapping for specified file already exists",
-            ErrVirtualAlloc(code) => format!("VirtualAlloc failure={}", code),
-            ErrCreateFileMappingW(code) => format!("CreateFileMappingW failure={}", code),
-            ErrMapViewOfFile(code) => format!("MapViewOfFile failure={}", code)
-        }
+impl fmt::Default for MapError {
+    fn fmt(val: &MapError, out: &mut fmt::Formatter) {
+        let str = match *val {
+            ErrFdNotAvail => "fd not available for reading or writing",
+            ErrInvalidFd => "Invalid fd",
+            ErrUnaligned => "Unaligned address, invalid flags, negative length or unaligned offset",
+            ErrNoMapSupport=> "File doesn't support mapping",
+            ErrNoMem => "Invalid address, or not enough available memory",
+            ErrUnsupProt => "Protection mode unsupported",
+            ErrUnsupOffset => "Offset in virtual memory mode is unsupported",
+            ErrAlreadyExists => "File mapping for specified file already exists",
+            ErrUnknown(code) => { write!(out.buf, "Unknown error = {}", code); return },
+            ErrVirtualAlloc(code) => { write!(out.buf, "VirtualAlloc failure = {}", code); return },
+            ErrCreateFileMappingW(code) => {
+                format!("CreateFileMappingW failure = {}", code);
+                return
+            },
+            ErrMapViewOfFile(code) => {
+                write!(out.buf, "MapViewOfFile failure = {}", code);
+                return
+            }
+        };
+        write!(out.buf, "{}", str);
     }
 }
 
@@ -1130,8 +1136,7 @@ impl Drop for MemoryMap {
         unsafe {
             match self.kind {
                 MapVirtual => {
-                    if libc::VirtualFree(self.data as *mut c_void,
-                                         self.len as size_t,
+                    if libc::VirtualFree(self.data as *mut c_void, 0,
                                          libc::MEM_RELEASE) == FALSE {
                         error!("VirtualFree failed: {}", errno());
                     }
@@ -1487,7 +1492,7 @@ mod tests {
             MapOffset(size / 2)
         ]) {
             Ok(chunk) => chunk,
-            Err(msg) => fail!(msg.to_str())
+            Err(msg) => fail!("{}", msg)
         };
         assert!(chunk.len > 0);
 
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
index f3fa482b18c..729e377e1af 100644
--- a/src/libstd/rt/env.rs
+++ b/src/libstd/rt/env.rs
@@ -10,7 +10,7 @@
 
 //! Runtime environment settings
 
-use from_str::FromStr;
+use from_str::from_str;
 use option::{Some, None};
 use os;
 
@@ -18,18 +18,25 @@ use os;
 // They are expected to be initialized once then left alone.
 
 static mut MIN_STACK: uint = 2 * 1024 * 1024;
+/// This default corresponds to 20M of cache per scheduler (at the default size).
+static mut MAX_CACHED_STACKS: uint = 10;
 static mut DEBUG_BORROW: bool = false;
 static mut POISON_ON_FREE: bool = false;
 
 pub fn init() {
     unsafe {
         match os::getenv("RUST_MIN_STACK") {
-            Some(s) => match FromStr::from_str(s) {
+            Some(s) => match from_str(s) {
                 Some(i) => MIN_STACK = i,
                 None => ()
             },
             None => ()
         }
+        match os::getenv("RUST_MAX_CACHED_STACKS") {
+            Some(max) => MAX_CACHED_STACKS = from_str(max).expect("expected positive integer in \
+                                                                   RUST_MAX_CACHED_STACKS"),
+            None => ()
+        }
         match os::getenv("RUST_DEBUG_BORROW") {
             Some(_) => DEBUG_BORROW = true,
             None => ()
@@ -45,6 +52,10 @@ pub fn min_stack() -> uint {
     unsafe { MIN_STACK }
 }
 
+pub fn max_cached_stacks() -> uint {
+    unsafe { MAX_CACHED_STACKS }
+}
+
 pub fn debug_borrow() -> bool {
     unsafe { DEBUG_BORROW }
 }