1
Fork 0

Add core::private::run_in_bare_thread

This begins executing Rust code in a fresh context with no runtime environment
This commit is contained in:
Brian Anderson 2013-01-10 19:03:13 -08:00
parent 4c441e95d6
commit 1b1700f44b
3 changed files with 67 additions and 0 deletions

View file

@ -37,6 +37,9 @@ extern mod rustrt {
unsafe fn rust_destroy_little_lock(lock: rust_little_lock);
unsafe fn rust_lock_little_lock(lock: rust_little_lock);
unsafe fn rust_unlock_little_lock(lock: rust_little_lock);
unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread;
unsafe fn rust_raw_thread_join_delete(thread: *raw_thread);
}
#[abi = "rust-intrinsic"]
@ -46,6 +49,37 @@ extern mod rusti {
fn atomic_xsub(dst: &mut int, src: int) -> int;
}
#[allow(non_camel_case_types)] // runtime type
type raw_thread = libc::c_void;
/**
Start a new thread outside of the current runtime context and wait for it to terminate.
The executing thread has no access to a task pointer and will be using a normal large stack.
*/
pub unsafe fn run_in_bare_thread(f: ~fn()) {
let (port, chan) = pipes::stream();
// XXX Unfortunate that this creates an extra scheduler but it's necessary
// since rust_raw_thread_join_delete is blocking
do task::spawn_sched(task::SingleThreaded) unsafe {
let closure: &fn() = || {
f()
};
let thread = rustrt::rust_raw_thread_start(closure);
rustrt::rust_raw_thread_join_delete(thread);
chan.send(());
}
port.recv();
}
#[test]
fn test_run_in_bare_thread() unsafe {
let i = 100;
do run_in_bare_thread {
assert i == 100;
}
}
#[allow(non_camel_case_types)] // runtime type
type rust_port_id = uint;

View file

@ -15,6 +15,7 @@
#include "rust_util.h"
#include "rust_scheduler.h"
#include "sync/timer.h"
#include "sync/rust_thread.h"
#include "rust_abi.h"
#include "rust_port.h"
@ -972,6 +973,36 @@ rust_log_str(uint32_t level, const char *str, size_t size) {
task->sched_loop->get_log().log(task, level, "%.*s", (int)size, str);
}
extern "C" CDECL void record_sp_limit(void *limit);
class raw_thread: public rust_thread {
public:
fn_env_pair *fn;
raw_thread(fn_env_pair *fn) : fn(fn) { }
virtual void run() {
record_sp_limit(0);
fn->f(NULL, fn->env, NULL);
}
};
extern "C" raw_thread*
rust_raw_thread_start(fn_env_pair *fn) {
assert(fn);
raw_thread *thread = new raw_thread(fn);
thread->start();
return thread;
}
extern "C" void
rust_raw_thread_join_delete(raw_thread *thread) {
assert(thread);
thread->join();
delete thread;
}
//
// Local Variables:
// mode: C++

View file

@ -208,3 +208,5 @@ linenoiseHistoryAdd
linenoiseHistorySetMaxLen
linenoiseHistorySave
linenoiseHistoryLoad
rust_raw_thread_start
rust_raw_thread_join_delete