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:
parent
4c441e95d6
commit
1b1700f44b
3 changed files with 67 additions and 0 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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++
|
||||
|
|
|
@ -208,3 +208,5 @@ linenoiseHistoryAdd
|
|||
linenoiseHistorySetMaxLen
|
||||
linenoiseHistorySave
|
||||
linenoiseHistoryLoad
|
||||
rust_raw_thread_start
|
||||
rust_raw_thread_join_delete
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue