From 835e963dbd6514473bfa234eb4423c8ceb478d52 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 17:39:59 -0700 Subject: std::rt: Improve the error message when the thread-local ptr is null Also fix some incorrect comments and variable names. --- src/libstd/rt/local_ptr.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs index cd7c5daa444..652e39b05c7 100644 --- a/src/libstd/rt/local_ptr.rs +++ b/src/libstd/rt/local_ptr.rs @@ -52,7 +52,9 @@ pub unsafe fn put(sched: ~T) { pub unsafe fn take() -> ~T { let key = tls_key(); let void_ptr: *mut c_void = tls::get(key); - rtassert!(void_ptr.is_not_null()); + if void_ptr.is_null() { + rtabort!("thread-local pointer is null. bogus!"); + } let ptr: ~T = cast::transmute(void_ptr); tls::set(key, ptr::mut_null()); return ptr; @@ -68,8 +70,8 @@ pub fn exists() -> bool { } } -/// Borrow the thread-local scheduler from thread-local storage. -/// While the scheduler is borrowed it is not available in TLS. +/// Borrow the thread-local value from thread-local storage. +/// While the value is borrowed it is not available in TLS. /// /// # Safety note /// @@ -88,21 +90,23 @@ pub unsafe fn borrow(f: &fn(&mut T)) { } } -/// Borrow a mutable reference to the thread-local Scheduler +/// Borrow a mutable reference to the thread-local value /// /// # Safety Note /// -/// Because this leaves the Scheduler in thread-local storage it is possible +/// Because this leaves the value in thread-local storage it is possible /// For the Scheduler pointer to be aliased pub unsafe fn unsafe_borrow() -> *mut T { let key = tls_key(); - let mut void_sched: *mut c_void = tls::get(key); - rtassert!(void_sched.is_not_null()); + let mut void_ptr: *mut c_void = tls::get(key); + if void_ptr.is_null() { + rtabort!("thread-local pointer is null. bogus!"); + } { - let sched: *mut *mut c_void = &mut void_sched; - let sched: *mut ~T = sched as *mut ~T; - let sched: *mut T = &mut **sched; - return sched; + 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; } } -- cgit 1.4.1-3-g733a5 From 75734a9cd355a7d122bc60dd059a825cf9616c7d Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 17:40:29 -0700 Subject: std::rt: Run the tests for Local in a bare thread Otherwise interferes with the existing runtime --- src/libstd/rt/local.rs | 81 ++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 36 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs index 7ab63233cff..131507196b1 100644 --- a/src/libstd/rt/local.rs +++ b/src/libstd/rt/local.rs @@ -126,6 +126,7 @@ impl Local for IoFactoryObject { #[cfg(test)] mod test { + use unstable::run_in_bare_thread; use rt::test::*; use super::*; use rt::task::Task; @@ -133,56 +134,64 @@ mod test { #[test] fn thread_local_task_smoke_test() { - local_ptr::init_tls_key(); - let mut sched = ~new_test_uv_sched(); - let task = ~Task::new_root(&mut sched.stack_pool, || {}); - Local::put(task); - let task: ~Task = Local::take(); - cleanup_task(task); + do run_in_bare_thread { + local_ptr::init_tls_key(); + let mut sched = ~new_test_uv_sched(); + let task = ~Task::new_root(&mut sched.stack_pool, || {}); + Local::put(task); + let task: ~Task = Local::take(); + cleanup_task(task); + } } #[test] fn thread_local_task_two_instances() { - local_ptr::init_tls_key(); - let mut sched = ~new_test_uv_sched(); - let task = ~Task::new_root(&mut sched.stack_pool, || {}); - Local::put(task); - let task: ~Task = Local::take(); - cleanup_task(task); - let task = ~Task::new_root(&mut sched.stack_pool, || {}); - Local::put(task); - let task: ~Task = Local::take(); - cleanup_task(task); + do run_in_bare_thread { + local_ptr::init_tls_key(); + let mut sched = ~new_test_uv_sched(); + let task = ~Task::new_root(&mut sched.stack_pool, || {}); + Local::put(task); + let task: ~Task = Local::take(); + cleanup_task(task); + let task = ~Task::new_root(&mut sched.stack_pool, || {}); + Local::put(task); + let task: ~Task = Local::take(); + cleanup_task(task); + } } #[test] fn borrow_smoke_test() { - local_ptr::init_tls_key(); - let mut sched = ~new_test_uv_sched(); - let task = ~Task::new_root(&mut sched.stack_pool, || {}); - Local::put(task); - - unsafe { - let _task: *mut Task = Local::unsafe_borrow(); + do run_in_bare_thread { + local_ptr::init_tls_key(); + let mut sched = ~new_test_uv_sched(); + let task = ~Task::new_root(&mut sched.stack_pool, || {}); + Local::put(task); + + unsafe { + let _task: *mut Task = Local::unsafe_borrow(); + } + let task: ~Task = Local::take(); + cleanup_task(task); } - let task: ~Task = Local::take(); - cleanup_task(task); } #[test] fn borrow_with_return() { - local_ptr::init_tls_key(); - let mut sched = ~new_test_uv_sched(); - let task = ~Task::new_root(&mut sched.stack_pool, || {}); - Local::put(task); - - let res = do Local::borrow:: |_task| { - true - }; - assert!(res) - let task: ~Task = Local::take(); - cleanup_task(task); + do run_in_bare_thread { + local_ptr::init_tls_key(); + let mut sched = ~new_test_uv_sched(); + let task = ~Task::new_root(&mut sched.stack_pool, || {}); + Local::put(task); + + let res = do Local::borrow:: |_task| { + true + }; + assert!(res) + let task: ~Task = Local::take(); + cleanup_task(task); + } } } -- cgit 1.4.1-3-g733a5 From f0f7e1b3fcfed8b77516a871ae82a4aa8df07764 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 23:28:47 -0700 Subject: std::rt: 3MB stacks! rustc needs *even more* megabytes when run without optimizations --- src/libstd/rt/task.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index abafe1cf209..ffe9f118b47 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -303,7 +303,7 @@ impl Task { impl Drop for Task { fn drop(&self) { rtdebug!("called drop for a task: %u", borrow::to_uint(self)); - assert!(self.destroyed) + rtassert!(self.destroyed) } } @@ -313,7 +313,7 @@ impl Drop for Task { impl Coroutine { pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine { - static MIN_STACK_SIZE: uint = 2000000; // XXX: Too much stack + static MIN_STACK_SIZE: uint = 3000000; // XXX: Too much stack let start = Coroutine::build_start_wrapper(start); let mut stack = stack_pool.take_segment(MIN_STACK_SIZE); -- cgit 1.4.1-3-g733a5 From a27f339cb4480e723aa7e06070683966d026d1ae Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 23:29:21 -0700 Subject: std::rt: Don't allow schedulers to exit before handling all messages Every time run_sched_once performs a 'scheduling action' it needs to guarantee that it runs at least one more time, so enqueue another run_sched_once callback. The primary reason it needs to do this is because not all async callbacks are guaranteed to run, it's only guaranteed that *a* callback will run after enqueing one - some may get dropped. At the moment this means we wastefully create lots of callbacks to ensure that there will *definitely* be a callback queued up to continue running the scheduler. The logic really needs to be tightened up here. --- src/libstd/rt/sched.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 18cfeade157..a5c8abc2a6c 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -172,6 +172,10 @@ impl Scheduler { rtdebug!("stopping scheduler %u", stask.sched.get_ref().sched_id()); + // Should not have any messages + let message = stask.sched.get_mut_ref().message_queue.pop(); + assert!(message.is_none()); + stask.destroyed = true; } @@ -336,11 +340,14 @@ impl Scheduler { match this.message_queue.pop() { Some(PinnedTask(task)) => { let mut task = task; + this.event_loop.callback(Scheduler::run_sched_once); task.give_home(Sched(this.make_handle())); this.resume_task_immediately(task); return None; } Some(TaskFromFriend(task)) => { + this.event_loop.callback(Scheduler::run_sched_once); + rtdebug!("got a task from a friend. lovely!"); return this.sched_schedule_task(task); } Some(Wake) => { @@ -395,6 +402,7 @@ impl Scheduler { /// Take a non-homed task we aren't allowed to run here and send /// it to the designated friend scheduler to execute. fn send_to_friend(&mut self, task: ~Task) { + rtdebug!("sending a task to friend"); match self.friend_handle { Some(ref mut handle) => { handle.send(TaskFromFriend(task)); @@ -426,12 +434,14 @@ impl Scheduler { Scheduler::send_task_home(task); return Some(this); } else { + this.event_loop.callback(Scheduler::run_sched_once); task.give_home(Sched(home_handle)); this.resume_task_immediately(task); return None; } } AnySched if this.run_anything => { + this.event_loop.callback(Scheduler::run_sched_once); task.give_home(AnySched); this.resume_task_immediately(task); return None; -- cgit 1.4.1-3-g733a5 From 2f8346b949169bd0f4b8fe0630eb4bc49ae35f11 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 3 Aug 2013 23:50:28 -0700 Subject: std::rt: Remove the test for context() This is no longer testable once newsched is turned on --- src/libstd/rt/mod.rs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 4cfe0efacfe..33e83fd9040 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -432,13 +432,3 @@ pub fn context() -> RuntimeContext { pub fn rust_try_get_task() -> *rust_task; } } - -#[test] -fn test_context() { - use unstable::run_in_bare_thread; - - assert_eq!(context(), OldTaskContext); - do run_in_bare_thread { - assert_eq!(context(), GlobalContext); - } -} -- cgit 1.4.1-3-g733a5