De-pub some private runtime components

This change was waiting for privacy to get sorted out, which should be true now
that #8215 has landed.

Closes #4427
This commit is contained in:
Alex Crichton 2013-10-09 10:34:27 -07:00
parent 8015f9c27e
commit 8b4423b04f
14 changed files with 114 additions and 99 deletions

View File

@ -739,7 +739,7 @@ fn get_concurrency() -> uint {
}
}
None => {
rt::util::default_sched_threads()
rt::default_sched_threads()
}
}
}

View File

@ -123,10 +123,10 @@ pub unsafe fn annihilate() {
if debug_mem() {
// We do logging here w/o allocation.
rterrln!("annihilator stats:\n \
total boxes: {}\n \
unique boxes: {}\n \
bytes freed: {}",
stats.n_total_boxes, stats.n_unique_boxes, stats.n_bytes_freed);
debug2!("annihilator stats:\n \
total boxes: {}\n \
unique boxes: {}\n \
bytes freed: {}",
stats.n_total_boxes, stats.n_unique_boxes, stats.n_bytes_freed);
}
}

View File

@ -1185,7 +1185,7 @@ pub fn last_os_error() -> ~str {
*/
pub fn set_exit_status(code: int) {
use rt;
rt::util::set_exit_status(code);
rt::set_exit_status(code);
}
unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] {

View File

@ -15,10 +15,10 @@ use option::{Option, None, Some};
use ptr::RawPtr;
use rt::env;
use rt::local::Local;
use rt::task;
use rt::task::Task;
use str::{OwnedStr, StrSlice};
use str;
use sys;
use uint;
use unstable::raw;
use vec::ImmutableVector;
@ -64,7 +64,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
None => { // not recording borrows
let msg = "borrowed";
do msg.with_c_str |msg_p| {
sys::begin_unwind_(msg_p, file, line);
task::begin_unwind(msg_p, file, line);
}
}
Some(borrow_list) => { // recording borrows
@ -80,7 +80,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
}
}
do msg.with_c_str |msg_p| {
sys::begin_unwind_(msg_p, file, line)
task::begin_unwind(msg_p, file, line)
}
}
}
@ -179,7 +179,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
if br.box != a || br.file != file || br.line != line {
let err = format!("wrong borrow found, br={:?}", br);
do err.with_c_str |msg_p| {
sys::begin_unwind_(msg_p, file, line)
task::begin_unwind(msg_p, file, line)
}
}
borrow_list

View File

@ -86,6 +86,17 @@ impl Drop for LocalHeap {
}
}
pub unsafe fn local_malloc(td: *libc::c_char, size: libc::uintptr_t) -> *libc::c_char {
// XXX: Unsafe borrow for speed. Lame.
let task: Option<*mut Task> = Local::try_unsafe_borrow();
match task {
Some(task) => {
(*task).heap.alloc(td as *libc::c_void, size as uint) as *libc::c_char
}
None => rtabort!("local malloc outside of task")
}
}
// A little compatibility function
pub unsafe fn local_free(ptr: *libc::c_char) {
// XXX: Unsafe borrow for speed. Lame.

View File

@ -178,5 +178,5 @@ pub fn maybe_tls_key() -> Option<tls::Key> {
#[inline]
#[cfg(test)]
pub fn maybe_tls_key() -> Option<tls::Key> {
unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
unsafe { ::cast::transmute(::realstd::rt::shouldnt_be_public::maybe_tls_key()) }
}

View File

@ -8,8 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Macros used by the runtime.
//!
//! These macros call functions which are only accessible in the `rt` module, so
//! they aren't defined anywhere outside of the `rt` module.
#[macro_escape];
#[doc(hidden)];
macro_rules! rterrln (
($($arg:tt)*) => ( {
@ -37,7 +41,7 @@ macro_rules! rtassert (
)
macro_rules! rtabort(
macro_rules! rtabort (
($($msg:tt)*) => ( {
::rt::util::abort(format!($($msg)*));
} )

View File

@ -76,6 +76,16 @@ use vec::{OwnedVector, MutableVector, ImmutableVector};
use self::thread::Thread;
use self::work_queue::WorkQueue;
// the os module needs to reach into this helper, so allow general access
// through this reexport.
pub use self::util::set_exit_status;
// this is somewhat useful when a program wants to spawn a "reasonable" number
// of workers based on the constraints of the system that it's running on.
// Perhaps this shouldn't be a `pub use` though and there should be another
// method...
pub use self::util::default_sched_threads;
// XXX: these probably shouldn't be public...
#[doc(hidden)]
pub mod shouldnt_be_public {
@ -86,8 +96,12 @@ pub mod shouldnt_be_public {
pub use super::select::SelectInner;
pub use super::rtio::EventLoop;
pub use super::select::{SelectInner, SelectPortInner};
pub use super::local_ptr::maybe_tls_key;
}
// Internal macros used by the runtime.
mod macros;
/// The global (exchange) heap.
pub mod global_heap;
@ -158,17 +172,14 @@ pub mod comm;
mod select;
// FIXME #5248 shouldn't be pub
/// The runtime needs to be able to put a pointer into thread-local storage.
pub mod local_ptr;
mod local_ptr;
// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
/// Bindings to pthread/windows thread-local storage.
pub mod thread_local_storage;
mod thread_local_storage;
// FIXME #5248 shouldn't be pub
/// Just stuff
pub mod util;
mod util;
// Global command line argument storage
pub mod args;

View File

@ -17,7 +17,7 @@ use borrow;
use cast::transmute;
use cleanup;
use local_data;
use libc::{c_void, uintptr_t};
use libc::{c_void, uintptr_t, c_char, size_t};
use prelude::*;
use option::{Option, Some, None};
use rt::borrowck;
@ -465,6 +465,48 @@ impl Unwinder {
}
}
/// This is the entry point of unwinding for things like lang items and such.
/// The arguments are normally generated by the compiler.
pub fn begin_unwind(msg: *c_char, file: *c_char, line: size_t) -> ! {
use rt::in_green_task_context;
use rt::task::Task;
use rt::local::Local;
use rt::logging::Logger;
use str::Str;
use c_str::CString;
unsafe {
let msg = CString::new(msg, false);
let file = CString::new(file, false);
let msg = match msg.as_str() {
Some(s) => s, None => rtabort!("message wasn't utf8?")
};
let file = match file.as_str() {
Some(s) => s, None => rtabort!("message wasn't utf8?")
};
if in_green_task_context() {
// Be careful not to allocate in this block, if we're failing we may
// have been failing due to a lack of memory in the first place...
do Local::borrow |task: &mut Task| {
let n = task.name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
format_args!(|args| { task.logger.log(args) },
"task '{}' failed at '{}', {}:{}",
n, msg, file, line);
}
} else {
rterrln!("failed in non-task context at '{}', {}:{}",
msg, file, line as int);
}
let task: *mut Task = Local::unsafe_borrow();
if (*task).unwinder.unwinding {
rtabort!("unwinding again");
}
(*task).unwinder.begin_unwind();
}
}
#[cfg(test)]
mod test {
use rt::test::*;

View File

@ -16,8 +16,6 @@ use option::{Some, None, Option};
use os;
use str::StrSlice;
use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
#[cfg(target_os="macos")]
use unstable::running_on_valgrind;
// Indicates whether we should perform expensive sanity checks, including rtassert!
@ -37,21 +35,17 @@ pub fn num_cpus() -> uint {
}
}
/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors wired into it; this
/// is a hard limit and requires rebuilding valgrind if you want to go beyond it. Normally this is
/// not a problem, but in some tests, we produce a lot of threads casually. Making lots of threads
/// alone might not be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv schedulers fork off
/// a separate thread for polling fsevents on OSX, we get a perfect storm of creating "too many
/// mappings" for valgrind to handle when running certain stress tests in the runtime.
#[cfg(target_os="macos")]
/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
/// wired into it; this is a hard limit and requires rebuilding valgrind if you
/// want to go beyond it. Normally this is not a problem, but in some tests, we
/// produce a lot of threads casually. Making lots of threads alone might not
/// be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
/// perfect storm of creating "too many mappings" for valgrind to handle when
/// running certain stress tests in the runtime.
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
running_on_valgrind()
}
#[cfg(not(target_os="macos"))]
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
false
(cfg!(target_os="macos")) && running_on_valgrind()
}
/// Get's the number of scheduler threads requested by the environment

View File

@ -88,9 +88,6 @@ pub mod linkhack {
}
}
// Internal macros
mod macros;
/* The Prelude. */
pub mod prelude;

View File

@ -14,9 +14,10 @@
use c_str::ToCStr;
use cast;
use libc::size_t;
use libc;
use libc::{c_char, size_t};
use repr;
use rt::task;
use str;
use unstable::intrinsics;
@ -109,7 +110,7 @@ impl FailWithCause for ~str {
fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
do cause.with_c_str |msg_buf| {
do file.with_c_str |file_buf| {
begin_unwind_(msg_buf, file_buf, line as libc::size_t)
task::begin_unwind(msg_buf, file_buf, line as libc::size_t)
}
}
}
@ -119,47 +120,12 @@ impl FailWithCause for &'static str {
fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
do cause.with_c_str |msg_buf| {
do file.with_c_str |file_buf| {
begin_unwind_(msg_buf, file_buf, line as libc::size_t)
task::begin_unwind(msg_buf, file_buf, line as libc::size_t)
}
}
}
}
// FIXME #4427: Temporary until rt::rt_fail_ goes away
pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
use rt::in_green_task_context;
use rt::task::Task;
use rt::local::Local;
use rt::logging::Logger;
use str::Str;
unsafe {
// XXX: Bad re-allocations. fail2! needs some refactoring
let msg = str::raw::from_c_str(msg);
let file = str::raw::from_c_str(file);
if in_green_task_context() {
// Be careful not to allocate in this block, if we're failing we may
// have been failing due to a lack of memory in the first place...
do Local::borrow |task: &mut Task| {
let n = task.name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
format_args!(|args| { task.logger.log(args) },
"task '{}' failed at '{}', {}:{}",
n, msg.as_slice(), file.as_slice(), line);
}
} else {
rterrln!("failed in non-task context at '{}', {}:{}",
msg, file, line as int);
}
let task: *mut Task = Local::unsafe_borrow();
if (*task).unwinder.unwinding {
rtabort!("unwinding again");
}
(*task).unwinder.begin_unwind();
}
}
#[cfg(test)]
mod tests {
use cast;

View File

@ -448,7 +448,7 @@ impl RuntimeGlue {
}
fn with_task_handle_and_failing(blk: &fn(&KillHandle, bool)) {
rtassert!(in_green_task_context());
assert!(in_green_task_context());
unsafe {
// Can't use safe borrow, because the taskgroup destructor needs to
// access the scheduler again to send kill signals to other tasks.
@ -458,7 +458,7 @@ impl RuntimeGlue {
}
fn with_my_taskgroup<U>(blk: &fn(&Taskgroup) -> U) -> U {
rtassert!(in_green_task_context());
assert!(in_green_task_context());
unsafe {
// Can't use safe borrow, because creating new hashmaps for the
// tasksets requires an rng, which needs to borrow the sched.
@ -553,7 +553,7 @@ fn enlist_many(child: &KillHandle, child_arc: &TaskGroupArc,
}
pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
rtassert!(in_green_task_context());
assert!(in_green_task_context());
let child_data = Cell::new(gen_child_taskgroup(opts.linked, opts.supervised));
let indestructible = opts.indestructible;
@ -631,7 +631,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
let (thread_port, thread_chan) = oneshot();
let thread_port_cell = Cell::new(thread_port);
let join_task = do Task::build_child(None) {
rtdebug!("running join task");
debug2!("running join task");
let thread_port = thread_port_cell.take();
let thread: Thread = thread_port.recv();
thread.join();
@ -648,11 +648,11 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
let join_task = join_task_cell.take();
let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool, None) || {
rtdebug!("boostrapping a 1:1 scheduler");
debug2!("boostrapping a 1:1 scheduler");
};
new_sched.bootstrap(bootstrap_task);
rtdebug!("enqueing join_task");
debug2!("enqueing join_task");
// Now tell the original scheduler to join with this thread
// by scheduling a thread-joining task on the original scheduler
orig_sched_handle.send_task_from_friend(join_task);
@ -684,7 +684,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
}
task.name = opts.name.take();
rtdebug!("spawn calling run_task");
debug2!("spawn calling run_task");
Scheduler::run_task(task);
}

View File

@ -12,16 +12,13 @@
use c_str::ToCStr;
use cast::transmute;
use libc::{c_char, c_void, size_t, uintptr_t};
use option::{Option, None, Some};
use sys;
use rt::task::Task;
use rt::local::Local;
use libc::{c_char, size_t, uintptr_t};
use rt::task;
use rt::borrowck;
#[lang="fail_"]
pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
sys::begin_unwind_(expr, file, line);
task::begin_unwind(expr, file, line);
}
#[lang="fail_bounds_check"]
@ -36,14 +33,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
#[lang="malloc"]
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
// XXX: Unsafe borrow for speed. Lame.
let task: Option<*mut Task> = Local::try_unsafe_borrow();
match task {
Some(task) => {
(*task).heap.alloc(td as *c_void, size as uint) as *c_char
}
None => rtabort!("local malloc outside of task")
}
::rt::local_heap::local_malloc(td, size)
}
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from