From 54e7bdc48e97d369acd51d1c08988fd946ccafd2 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 29 Aug 2013 20:57:37 +1000 Subject: [PATCH 1/4] rt: Handle non-integer RUST_THREADS (slightly) more gracefully. Previously it would call Option.unwrap(), which calls `fail!` on None, which doesn't work without the runtime (e.g. when initialising it). --- src/libstd/rt/util.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 9113f03ffee..6f39cbbade3 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -11,7 +11,7 @@ use container::Container; use from_str::FromStr; use libc; -use option::{Some, None}; +use option::{Some, None, Option}; use os; use str::StrSlice; use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst}; @@ -57,7 +57,13 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool { /// either `RUST_THREADS` or `num_cpus`. pub fn default_sched_threads() -> uint { match os::getenv("RUST_THREADS") { - Some(nstr) => FromStr::from_str(nstr).unwrap(), + Some(nstr) => { + let opt_n: Option = FromStr::from_str(nstr); + match opt_n { + Some(n) if n > 0 => n, + _ => rtabort!("`RUST_THREADS` is `%s`, should be a positive integer", nstr) + } + } None => { if limit_thread_creation_due_to_osx_and_valgrind() { 1 From 440f1e2dadaf7c56575b65aa13c30abf9d5cec26 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 29 Aug 2013 21:49:55 +1000 Subject: [PATCH 2/4] rt: use sugary functions rather than manual range loops. --- src/libstd/rt/args.rs | 9 ++++----- src/libstd/rt/mod.rs | 18 +++++++----------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index baaf3d44e79..e5075f8818a 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -55,10 +55,11 @@ pub fn clone() -> Option<~[~str]> { mod imp { use libc; use option::{Option, Some, None}; - use iterator::{Iterator, range}; + use iterator::Iterator; use str; use unstable::finally::Finally; use util; + use vec; pub unsafe fn init(argc: int, argv: **u8) { let args = load_argc_and_argv(argc, argv); @@ -111,11 +112,9 @@ mod imp { // Copied from `os`. unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] { - let mut args = ~[]; - for i in range(0u, argc as uint) { - args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int))); + do vec::from_fn(argc as uint) |i| { + str::raw::from_c_str(*(argv as **libc::c_char).offset(i as int)) } - args } #[cfg(stage0)] diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 7728a388c65..14ff1fd5804 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -59,7 +59,7 @@ Several modules in `core` are clients of `rt`: use cell::Cell; use clone::Clone; use container::Container; -use iterator::{Iterator, range}; +use iterator::Iterator; use option::{Option, None, Some}; use ptr::RawPtr; use rt::local::Local; @@ -71,7 +71,8 @@ use rt::work_queue::WorkQueue; use rt::uv::uvio::UvEventLoop; use unstable::atomics::{AtomicInt, SeqCst}; use unstable::sync::UnsafeArc; -use vec::{OwnedVector, MutableVector}; +use vec; +use vec::{OwnedVector, MutableVector, ImmutableVector}; /// The global (exchange) heap. pub mod global_heap; @@ -251,11 +252,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { // Create a work queue for each scheduler, ntimes. Create an extra // for the main thread if that flag is set. We won't steal from it. - let mut work_queues = ~[]; - for _ in range(0u, nscheds) { - let work_queue: WorkQueue<~Task> = WorkQueue::new(); - work_queues.push(work_queue); - } + let work_queues: ~[WorkQueue<~Task>] = vec::from_fn(nscheds, |_| WorkQueue::new()); // The schedulers. let mut scheds = ~[]; @@ -263,13 +260,13 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { // sent the Shutdown message to terminate the schedulers. let mut handles = ~[]; - for i in range(0u, nscheds) { + for work_queue in work_queues.iter() { rtdebug!("inserting a regular scheduler"); // Every scheduler is driven by an I/O event loop. let loop_ = ~UvEventLoop::new(); let mut sched = ~Scheduler::new(loop_, - work_queues[i].clone(), + work_queue.clone(), work_queues.clone(), sleepers.clone()); let handle = sched.make_handle(); @@ -358,9 +355,8 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int { } // Run each remaining scheduler in a thread. - while !scheds.is_empty() { + for sched in scheds.move_rev_iter() { rtdebug!("creating regular schedulers"); - let sched = scheds.pop(); let sched_cell = Cell::new(sched); let thread = do Thread::start { let mut sched = sched_cell.take(); From e835c6b042b88720d5fd0d606d25e0ea4fa27b1a Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 29 Aug 2013 22:28:49 +1000 Subject: [PATCH 3/4] rt: remove a series of unfortunate casts. --- src/libstd/rt/local_ptr.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs index e843fd1adef..3f9b7fc83df 100644 --- a/src/libstd/rt/local_ptr.rs +++ b/src/libstd/rt/local_ptr.rs @@ -121,27 +121,20 @@ pub unsafe fn borrow(f: &fn(&mut T)) { /// For the Scheduler pointer to be aliased pub unsafe fn unsafe_borrow() -> *mut T { let key = tls_key(); - let mut void_ptr: *mut c_void = tls::get(key); + let void_ptr = tls::get(key); if void_ptr.is_null() { rtabort!("thread-local pointer is null. bogus!"); } - let ptr: *mut *mut c_void = &mut void_ptr; - let ptr: *mut ~T = ptr as *mut ~T; - let ptr: *mut T = &mut **ptr; - return ptr; + void_ptr as *mut T } pub unsafe fn try_unsafe_borrow() -> Option<*mut T> { let key = tls_key(); - let mut void_ptr: *mut c_void = tls::get(key); + let void_ptr = tls::get(key); if void_ptr.is_null() { - return None; - } - { - let ptr: *mut *mut c_void = &mut void_ptr; - let ptr: *mut ~T = ptr as *mut ~T; - let ptr: *mut T = &mut **ptr; - return Some(ptr); + None + } else { + Some(void_ptr as *mut T) } } From 4fea236a85b61b52fc3e16348886ff32f5b8210b Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 29 Aug 2013 22:58:27 +1000 Subject: [PATCH 4/4] extra: error message should reflact that RUST_TEST_TASKS should be strictly positive (zero is illegal). --- src/libextra/test.rs | 2 +- ...est-threads-invalid-value.rs => test-tasks-invalid-value.rs} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/test/run-fail/{test-threads-invalid-value.rs => test-tasks-invalid-value.rs} (92%) diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 82b62c7dfc0..73f6d2e1bda 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -745,7 +745,7 @@ fn get_concurrency() -> uint { let opt_n: Option = FromStr::from_str(s); match opt_n { Some(n) if n > 0 => n, - _ => fail!("RUST_TEST_TASKS is `%s`, should be a non-negative integer.", s) + _ => fail!("RUST_TEST_TASKS is `%s`, should be a positive integer.", s) } } None => { diff --git a/src/test/run-fail/test-threads-invalid-value.rs b/src/test/run-fail/test-tasks-invalid-value.rs similarity index 92% rename from src/test/run-fail/test-threads-invalid-value.rs rename to src/test/run-fail/test-tasks-invalid-value.rs index 0050d24e1d0..74531deb58e 100644 --- a/src/test/run-fail/test-threads-invalid-value.rs +++ b/src/test/run-fail/test-tasks-invalid-value.rs @@ -11,7 +11,7 @@ // This checks that RUST_TEST_TASKS not being 1, 2, ... is detected // properly. -// error-pattern:should be a non-negative integer +// error-pattern:should be a positive integer // compile-flags: --test // exec-env:RUST_TEST_TASKS=foo