From 78348b4398d3373163f66614ed76ce80b466c27b Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 24 Jun 2011 15:37:10 -0700 Subject: [PATCH 1/9] Removing runtime tests. The runtime is tested well enough by the standard library tests, so we might as well have less code to fix during refactoring. --- mk/rt.mk | 6 --- src/rt/rust_internal.h | 4 -- src/rt/test/rust_test_harness.cpp | 40 ---------------- src/rt/test/rust_test_harness.h | 22 --------- src/rt/test/rust_test_runtime.cpp | 73 ----------------------------- src/rt/test/rust_test_runtime.h | 51 -------------------- src/rt/test/rust_test_util.cpp | 78 ------------------------------- src/rt/test/rust_test_util.h | 41 ---------------- 8 files changed, 315 deletions(-) delete mode 100644 src/rt/test/rust_test_harness.cpp delete mode 100644 src/rt/test/rust_test_harness.h delete mode 100644 src/rt/test/rust_test_runtime.cpp delete mode 100644 src/rt/test/rust_test_runtime.h delete mode 100644 src/rt/test/rust_test_util.cpp delete mode 100644 src/rt/test/rust_test_util.h diff --git a/mk/rt.mk b/mk/rt.mk index d25c866ec16f9..b4cdefd996ce5 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -25,9 +25,6 @@ RUNTIME_CS := rt/sync/timer.cpp \ rt/rust_srv.cpp \ rt/rust_kernel.cpp \ rt/memory_region.cpp \ - rt/test/rust_test_harness.cpp \ - rt/test/rust_test_runtime.cpp \ - rt/test/rust_test_util.cpp \ rt/arch/i386/context.cpp \ RUNTIME_LL := @@ -59,9 +56,6 @@ RUNTIME_HDR := rt/globals.h \ rt/rust_kernel.h \ rt/memory_region.h \ rt/memory.h \ - rt/test/rust_test_harness.h \ - rt/test/rust_test_runtime.h \ - rt/test/rust_test_util.h \ rt/arch/i386/context.h \ RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX) diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 5db1216c1021e..cc494a261486a 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -280,10 +280,6 @@ struct gc_alloc { #include "rust_chan.h" #include "rust_port.h" -#include "test/rust_test_harness.h" -#include "test/rust_test_util.h" -#include "test/rust_test_runtime.h" - // // Local Variables: // mode: C++ diff --git a/src/rt/test/rust_test_harness.cpp b/src/rt/test/rust_test_harness.cpp deleted file mode 100644 index cca199dcdb98b..0000000000000 --- a/src/rt/test/rust_test_harness.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "../rust_internal.h" - -bool -rust_test::run() { - return false; -} - -const char * -rust_test::name() { - return "untitled"; -} - -rust_test_suite::rust_test_suite() { - tests.append(new rust_domain_test()); - tests.append(new rust_task_test(this)); - tests.append(new rust_array_list_test()); - tests.append(new rust_synchronized_indexed_list_test()); -} - -rust_test_suite::~rust_test_suite() { - -} - -bool -rust_test_suite::run() { - bool pass = true; - for (size_t i = 0; i < tests.size(); i++) { - rust_test *test = tests[i]; - printf("test: %s running ... \n", test->name()); - timer timer; - bool result = tests[i]->run(); - printf("test: %s %s %.2f ms\n", test->name(), - result ? "PASSED" : "FAILE", timer.get_elapsed_time_in_ms()); - if (result == false) { - pass = false; - } - } - return pass; -} - diff --git a/src/rt/test/rust_test_harness.h b/src/rt/test/rust_test_harness.h deleted file mode 100644 index 401015e450890..0000000000000 --- a/src/rt/test/rust_test_harness.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef RUST_TEST_HARNESS_H -#define RUST_TEST_HARNESS_H - -#define CHECK(x) if ((x) == false) \ - { printf("condition: %s failed at file: %s, line: %d\n", #x, \ - __FILE__, __LINE__ ); return false; } - -class rust_test { -public: - virtual bool run(); - virtual const char *name(); -}; - -class rust_test_suite : public rust_test { -public: - array_list tests; - rust_test_suite(); - virtual ~rust_test_suite(); - bool run(); -}; - -#endif /* RUST_TEST_HARNESS_H */ diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp deleted file mode 100644 index cf82818c4ff0a..0000000000000 --- a/src/rt/test/rust_test_runtime.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "rust_test_runtime.h" - -rust_test_runtime::rust_test_runtime() { -} - -rust_test_runtime::~rust_test_runtime() { -} - -#define DOMAINS 32 -#define TASKS 32 - -void -rust_domain_test::worker::run() { - rust_handle *handle = kernel->create_domain("test"); - for (int i = 0; i < TASKS; i++) { - handle->referent()->create_task(NULL, "child"); - } - sync::random_sleep(1000); - kernel->destroy_domain(handle->_referent); -} - -bool -rust_domain_test::run() { - rust_srv srv; - rust_kernel kernel(&srv); - - array_list workers; - for (int i = 0; i < DOMAINS; i++) { - worker *worker = new rust_domain_test::worker (&kernel); - workers.append(worker); - worker->start(); - } - - // We don't join the worker threads here in order to simulate ad-hoc - // termination of domains. If we join_all_domains before all domains - // are actually spawned, this could crash, thus the reason for the - // sleep below. - - sync::sleep(100); - kernel.join_all_domains(); - return true; -} - -void task_entry() { - printf("task entry\n"); -} - -void -rust_task_test::worker::run() { - rust_handle *handle = - kernel->create_domain("test"); - rust_dom *domain = handle->referent(); - domain->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL); - domain->start_main_loop(0); - kernel->destroy_domain(domain); -} - -bool -rust_task_test::run() { - rust_srv srv; - rust_kernel kernel(&srv); - - array_list workers; - for (int i = 0; i < DOMAINS; i++) { - worker *worker = new rust_task_test::worker (&kernel, this); - workers.append(worker); - worker->start(); - } - - sync::random_sleep(1000); - kernel.join_all_domains(); - return true; -} diff --git a/src/rt/test/rust_test_runtime.h b/src/rt/test/rust_test_runtime.h deleted file mode 100644 index 8d4f38ecb79f5..0000000000000 --- a/src/rt/test/rust_test_runtime.h +++ /dev/null @@ -1,51 +0,0 @@ -#include "../rust_internal.h" - -#ifndef RUST_TEST_RUNTIME_H -#define RUST_TEST_RUNTIME_H - -class rust_test_runtime { -public: - rust_test_runtime(); - virtual ~rust_test_runtime(); -}; - - -class rust_domain_test : public rust_test { -public: - class worker : public rust_thread { - public: - rust_kernel *kernel; - worker(rust_kernel *kernel) : kernel(kernel) { - // Nop. - } - void run(); - }; - bool run(); - const char *name() { - return "rust_domain_test"; - } -}; - -class rust_task_test : public rust_test { -public: - rust_test_suite *suite; - rust_task_test(rust_test_suite *suite) : suite(suite) { - // Nop. - } - class worker : public rust_thread { - public: - rust_kernel *kernel; - rust_task_test *parent; - worker(rust_kernel *kernel, rust_task_test *parent) : - kernel(kernel), parent(parent) { - // Nop. - } - void run(); - }; - bool run(); - const char *name() { - return "rust_task_test"; - } -}; - -#endif /* RUST_TEST_RUNTIME_H */ diff --git a/src/rt/test/rust_test_util.cpp b/src/rt/test/rust_test_util.cpp deleted file mode 100644 index 2e9d764f69b66..0000000000000 --- a/src/rt/test/rust_test_util.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "../rust_internal.h" - -#define COUNT 1000 -#define LARGE_COUNT 10000 -#define THREADS 10 - -bool -rust_array_list_test::run() { - array_list list; - - for (int i = 0; i < COUNT; i++) { - list.append(i); - } - - for (int i = 0; i < COUNT; i++) { - CHECK (list[i] == i); - } - - for (int i = 0; i < COUNT; i++) { - CHECK (list.index_of(i) == i); - } - - for (int i = 0; i < COUNT; i++) { - CHECK (list.replace(i, -i)); - CHECK (list.replace(-i, i)); - CHECK (list.index_of(i) == i); - } - - for (int i = COUNT - 1; i >= 0; i--) { - CHECK (list.pop(NULL)); - } - - return true; -} - -bool -rust_synchronized_indexed_list_test::run() { - array_list workers; - - for (int i = 0; i < THREADS; i++) { - worker *worker = - new rust_synchronized_indexed_list_test::worker(this); - workers.append(worker); - } - - for (uint32_t i = 0; i < workers.size(); i++) { - workers[i]->start(); - } - - while(workers.is_empty() == false) { - worker *worker; - workers.pop(&worker); - worker->join(); - delete worker; - } - - long long expected_items = LARGE_COUNT * THREADS; - - CHECK(list.length() == expected_items); - - long long sum = 0; - for (size_t i = 0; i < list.length(); i++) { - sum += list[i]->value; - } - - long long expected_sum = LARGE_COUNT; - expected_sum = expected_sum * (expected_sum - 1) / 2 * THREADS; - CHECK (sum == expected_sum); - return true; -} - -void -rust_synchronized_indexed_list_test::worker::run() { - for (int i = 0; i < LARGE_COUNT; i++) { - parent->list.append(new indexed_list_element(i)); - } - return; -} diff --git a/src/rt/test/rust_test_util.h b/src/rt/test/rust_test_util.h deleted file mode 100644 index 41c3579043a15..0000000000000 --- a/src/rt/test/rust_test_util.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef RUST_TEST_UTIL_H -#define RUST_TEST_UTIL_H - -class rust_test_util : public rust_test { -public: - -}; - -class rust_array_list_test : public rust_test { -public: - bool run(); - const char *name() { - return "rust_array_list_test"; - } -}; - - -class rust_synchronized_indexed_list_test : public rust_test { -public: - rust_srv srv; - synchronized_indexed_list > list; - - rust_synchronized_indexed_list_test() { - // Nop. - } - - class worker : public rust_thread { - public: - rust_synchronized_indexed_list_test *parent; - worker(rust_synchronized_indexed_list_test *parent) : parent(parent) { - // Nop. - } - void run(); - }; - bool run(); - const char *name() { - return "rust_synchronized_indexed_list_test"; - } -}; - -#endif /* RUST_TEST_UTIL_H */ From 449d95cc227e7a7ad5494cb93008f112897a60ac Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 24 Jun 2011 15:56:12 -0700 Subject: [PATCH 2/9] There is only one domain per kernel now. --- src/comp/back/upcall.rs | 6 ---- src/rt/rust.cpp | 5 +-- src/rt/rust_kernel.cpp | 41 +++++++-------------- src/rt/rust_kernel.h | 20 ++++------- src/rt/rust_upcall.cpp | 80 ----------------------------------------- src/rt/rustrt.def.in | 2 -- 6 files changed, 21 insertions(+), 133 deletions(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 1a5a9a8d25461..1ed0d4bbf9c25 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -55,8 +55,6 @@ type upcalls = ValueRef get_type_desc, ValueRef new_task, ValueRef start_task, - ValueRef new_thread, - ValueRef start_thread, ValueRef ivec_resize, ValueRef ivec_spill); @@ -118,10 +116,6 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { start_task=d("start_task", [T_taskptr(tn), T_int(), T_int(), T_size_t()], T_taskptr(tn)), - new_thread=d("new_thread", [T_ptr(T_i8())], T_taskptr(tn)), - start_thread=d("start_thread", - [T_taskptr(tn), T_int(), T_int(), T_int(), - T_size_t()], T_taskptr(tn)), ivec_resize=d("ivec_resize", [T_ptr(T_opaque_ivec()), T_int()], T_void()), ivec_spill=d("ivec_spill", [T_ptr(T_opaque_ivec()), T_int()], diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 093656b77d2ab..1de1685692d25 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -96,8 +96,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { rust_srv *srv = new rust_srv(); rust_kernel *kernel = new rust_kernel(srv); kernel->start(); - rust_handle *handle = kernel->create_domain("main"); - rust_dom *dom = handle->referent(); + rust_dom *dom = kernel->get_domain(); command_line_args *args = new (dom) command_line_args(dom, argc, argv); DLOG(dom, dom, "startup: %d args in 0x%" PRIxPTR, @@ -114,8 +113,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { int ret = dom->start_main_loops(num_threads); delete args; - kernel->destroy_domain(dom); - kernel->join_all_domains(); delete kernel; delete srv; diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index f72da483c3502..9af5f9e2b4120 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -11,11 +11,12 @@ rust_kernel::rust_kernel(rust_srv *srv) : _region(&srv->local_region), _log(srv, NULL), _srv(srv), - _interrupt_kernel_loop(FALSE) { - // Nop. + _interrupt_kernel_loop(FALSE) +{ + dom = create_domain("main"); } -rust_handle * +rust_dom * rust_kernel::create_domain(const char *name) { _kernel_lock.lock(); rust_message_queue *message_queue = @@ -25,21 +26,19 @@ rust_kernel::create_domain(const char *name) { new (this) rust_dom(this, message_queue, srv, name); rust_handle *handle = internal_get_dom_handle(dom); message_queue->associate(handle); - domains.append(dom); message_queues.append(message_queue); - KLOG("created domain: " PTR ", name: %s, index: %d, domains %d", - dom, name, dom->list_index, domains.length()); + KLOG("created domain: " PTR ", name: %s, index: %d", + dom, name, dom->list_index); _kernel_lock.signal_all(); _kernel_lock.unlock(); - return handle; + return dom; } void -rust_kernel::destroy_domain(rust_dom *dom) { +rust_kernel::destroy_domain() { _kernel_lock.lock(); - KLOG("deleting domain: " PTR ", name: %s, index: %d, domains %d", - dom, dom->name, dom->list_index, domains.length()); - domains.remove(dom); + KLOG("deleting domain: " PTR ", name: %s, index: %d", + dom, dom->name, dom->list_index); dom->message_queue->disassociate(); rust_srv *srv = dom->srv; delete dom; @@ -96,22 +95,10 @@ rust_kernel::get_port_handle(rust_port *port) { return handle; } -void -rust_kernel::join_all_domains() { - _kernel_lock.lock(); - while (domains.length() > 0) { - _kernel_lock.wait(); - } - _kernel_lock.unlock(); - KLOG("joined domains"); -} - void rust_kernel::log_all_domain_state() { - KLOG("log_all_domain_state: %d domains", domains.length()); - for (uint32_t i = 0; i < domains.length(); i++) { - domains[i]->log_state(); - } + KLOG("log_all_domain_state"); + dom->log_state(); } /** @@ -172,9 +159,7 @@ rust_kernel::terminate_kernel_loop() { } rust_kernel::~rust_kernel() { - K(_srv, domains.length() == 0, - "Kernel has %d live domain(s), join all domains before killing " - "the kernel.", domains.length()); + destroy_domain(); terminate_kernel_loop(); diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 0c3df20358a5c..70495d029bc13 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -44,6 +44,8 @@ class rust_kernel : public rust_thread { rust_log _log; rust_srv *_srv; + rust_dom *dom; + /** * Task proxy objects are kernel owned handles to Rust objects. */ @@ -64,12 +66,10 @@ class rust_kernel : public rust_thread { rust_handle *internal_get_dom_handle(rust_dom *dom); -public: + rust_dom *create_domain(const char *name); + void destroy_domain(); - /** - * List of domains that are currently executing. - */ - indexed_list domains; +public: /** * Message queues are kernel objects and are associated with domains. @@ -86,9 +86,6 @@ class rust_kernel : public rust_thread { rust_kernel(rust_srv *srv); - rust_handle *create_domain(const char *name); - void destroy_domain(rust_dom *dom); - bool is_deadlocked(); void signal_kernel_lock(); @@ -101,17 +98,14 @@ class rust_kernel : public rust_thread { void notify_message_enqueued(rust_message_queue *queue, rust_message *message); - /** - * Blocks until all domains have terminated. - */ - void join_all_domains(); - void log_all_domain_state(); void log(uint32_t level, char const *fmt, ...); virtual ~rust_kernel(); void *malloc(size_t size); void free(void *mem); + + inline rust_dom *get_domain() const { return dom; } }; inline void *operator new(size_t size, rust_kernel *kernel) { diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 0947c44b2c960..a769051b7eb4d 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -556,86 +556,6 @@ upcall_start_task(rust_task *spawner, return task; } -/** - * Called whenever a new domain is created. - */ -extern "C" CDECL maybe_proxy * -upcall_new_thread(rust_task *task, const char *name) { - I(task->dom, false); - LOG_UPCALL_ENTRY(task); - rust_dom *parent_dom = task->dom; - rust_kernel *kernel = parent_dom->kernel; - rust_handle *child_dom_handle = - kernel->create_domain(name); - rust_handle *child_task_handle = - kernel->get_task_handle(child_dom_handle->referent()->root_task); - LOG(task, mem, "child name: %s, child_dom_handle: " PTR - ", child_task_handle: " PTR, - name, child_dom_handle, child_task_handle); - rust_proxy *child_task_proxy = - new rust_proxy (child_task_handle); - return child_task_proxy; -} - -#if 0 /* FIXME: this code will be re-enabled once we have multithreading. */ - -#if defined(__WIN32__) -static DWORD WINAPI rust_thread_start(void *ptr) -#elif defined(__GNUC__) -static void *rust_thread_start(void *ptr) -#else -#error "Platform not supported" -#endif -{ - // We were handed the domain we are supposed to run. - rust_dom *dom = (rust_dom *) ptr; - - // Start a new rust main loop for this thread. - dom->start_main_loop(); - - // Destroy the domain. - dom->kernel->destroy_domain(dom); - - return 0; -} - -#endif - -/** - * Called after a new domain is created. Here we create a new thread and - * and start the domain main loop. - */ -extern "C" CDECL maybe_proxy * -upcall_start_thread(rust_task *task, - rust_proxy *child_task_proxy, - uintptr_t spawnee_fn, - size_t callsz) { - I(task->dom, false); - LOG_UPCALL_ENTRY(task); -#if 0 - rust_dom *parenet_dom = task->dom; - rust_handle *child_task_handle = child_task_proxy->handle(); - LOG(task, task, - "spawnee_fn " PTR - ", callsz %" PRIdPTR ")", - spawnee_fn, callsz); - rust_task *child_task = child_task_handle->referent(); - child_task->start(spawnee_fn, - task->rust_sp, callsz); -#if defined(__WIN32__) - HANDLE thread; - thread = CreateThread(NULL, 0, rust_thread_start, child_task->dom, 0, - NULL); - parenet_dom->win32_require("CreateThread", thread != NULL); -#else - pthread_t thread; - pthread_create(&thread, &parenet_dom->attr, rust_thread_start, - (void *) child_task->dom); -#endif -#endif // 0 - return child_task_proxy; -} - /** * Resizes an interior vector that has been spilled to the heap. */ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 17b4ba9817d25..f3212bbeb000d 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -67,13 +67,11 @@ upcall_new_chan upcall_new_port upcall_new_str upcall_new_task -upcall_new_thread upcall_new_vec upcall_recv upcall_send upcall_sleep upcall_start_task -upcall_start_thread upcall_trace_str upcall_trace_word upcall_vec_append From 7eb487651ef3048120acc50e8a984815cf5d0d1d Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 24 Jun 2011 16:50:06 -0700 Subject: [PATCH 3/9] Moved thread management to rust_kernel. --- src/rt/rust.cpp | 2 +- src/rt/rust_builtin.cpp | 6 ++--- src/rt/rust_dom.cpp | 51 ++++++++--------------------------------- src/rt/rust_dom.h | 14 ----------- src/rt/rust_kernel.cpp | 31 +++++++++++++++++++++++++ src/rt/rust_kernel.h | 23 +++++++++++++++++-- src/rt/rust_task.cpp | 11 +++++---- src/rt/rust_task.h | 1 + src/rt/rust_upcall.cpp | 38 +++++++++++++++--------------- 9 files changed, 91 insertions(+), 86 deletions(-) diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 1de1685692d25..2a491b611509d 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -111,7 +111,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { DLOG(dom, dom, "Using %d worker threads.", num_threads); - int ret = dom->start_main_loops(num_threads); + int ret = kernel->start_task_threads(num_threads); delete args; delete kernel; delete srv; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 27fe45e42d7a1..2a724ee179134 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -391,16 +391,16 @@ task_yield(rust_task *task) { extern "C" CDECL void task_join(rust_task *task, rust_task *join_task) { - task->dom->scheduler_lock.lock(); + task->kernel->scheduler_lock.lock(); // If the other task is already dying, we don't have to wait for it. if (join_task->dead() == false) { join_task->tasks_waiting_to_join.push(task); task->block(join_task, "joining local task"); - task->dom->scheduler_lock.unlock(); + task->kernel->scheduler_lock.unlock(); task->yield(2); } else { - task->dom->scheduler_lock.unlock(); + task->kernel->scheduler_lock.unlock(); } } diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index c9c6b56c09ee0..65ccf158b64a3 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -51,9 +51,9 @@ rust_dom::activate(rust_task *task) { task->ctx.next = &ctx; DLOG(this, task, "descheduling..."); - scheduler_lock.unlock(); + kernel->scheduler_lock.unlock(); task->ctx.swap(ctx); - scheduler_lock.lock(); + kernel->scheduler_lock.lock(); DLOG(this, task, "task has returned"); } @@ -167,7 +167,7 @@ rust_dom::number_of_live_tasks() { */ void rust_dom::reap_dead_tasks() { - I(this, scheduler_lock.lock_held_by_current_thread()); + I(this, kernel->scheduler_lock.lock_held_by_current_thread()); for (size_t i = 0; i < dead_tasks.length(); ) { rust_task *task = dead_tasks[i]; // Make sure this task isn't still running somewhere else... @@ -266,7 +266,7 @@ rust_dom::log_state() { */ int rust_dom::start_main_loop(int id) { - scheduler_lock.lock(); + kernel->scheduler_lock.lock(); // Make sure someone is watching, to pull us out of infinite loops. // @@ -296,9 +296,9 @@ rust_dom::start_main_loop(int id) { DLOG(this, task, "all tasks are blocked, scheduler id %d yielding ...", id); - scheduler_lock.unlock(); + kernel->scheduler_lock.unlock(); sync::sleep(100); - scheduler_lock.lock(); + kernel->scheduler_lock.lock(); DLOG(this, task, "scheduler resuming ..."); continue; @@ -349,9 +349,9 @@ rust_dom::start_main_loop(int id) { "scheduler yielding ...", dead_tasks.length()); log_state(); - scheduler_lock.unlock(); + kernel->scheduler_lock.unlock(); sync::yield(); - scheduler_lock.lock(); + kernel->scheduler_lock.lock(); } else { drain_incoming_message_queue(true); } @@ -360,28 +360,7 @@ rust_dom::start_main_loop(int id) { DLOG(this, dom, "finished main-loop %d (dom.rval = %d)", id, rval); - scheduler_lock.unlock(); - return rval; -} - -int rust_dom::start_main_loops(int num_threads) -{ - dom_worker *worker = NULL; - - // -1, because this thread will also be a worker. - for(int i = 0; i < num_threads - 1; ++i) { - worker = new dom_worker(i + 1, this); - worker->start(); - threads.push(worker); - } - - start_main_loop(0); - - while(threads.pop(&worker)) { - worker->join(); - delete worker; - } - + kernel->scheduler_lock.unlock(); return rval; } @@ -392,26 +371,14 @@ rust_dom::get_cache() { rust_task * rust_dom::create_task(rust_task *spawner, const char *name) { - //scheduler_lock.lock(); rust_task *task = new (this) rust_task (this, &newborn_tasks, spawner, name); DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s", task, spawner ? spawner->name : "null", name); newborn_tasks.append(task); - //scheduler_lock.unlock(); return task; } -rust_dom::dom_worker::dom_worker(int id, rust_dom *owner) - : id(id), owner(owner) -{ -} - -void rust_dom::dom_worker::run() -{ - owner->start_main_loop(id); -} - // // Local Variables: // mode: C++ diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h index 7f9fa7a2901ed..dfc0960a9ea90 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_dom.h @@ -97,24 +97,10 @@ struct rust_dom : public kernel_owned, rc_base rust_task *schedule_task(); int start_main_loop(int id); - int start_main_loops(int num_threads); void log_state(); rust_task *create_task(rust_task *spawner, const char *name); - - class dom_worker : public rust_thread { - int id; - rust_dom *owner; - - public: - dom_worker(int id, rust_dom *owner); - - virtual void run(); - }; - - lock_and_signal scheduler_lock; - array_list threads; }; inline rust_log & diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 9af5f9e2b4120..5e495b8c822b2 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -224,6 +224,37 @@ rust_kernel::signal_kernel_lock() { _kernel_lock.unlock(); } +int rust_kernel::start_task_threads(int num_threads) +{ + rust_task_thread *thread = NULL; + + // -1, because this thread will also be a thread. + for(int i = 0; i < num_threads - 1; ++i) { + thread = new rust_task_thread(i + 1, this); + thread->start(); + threads.push(thread); + } + + dom->start_main_loop(0); + + while(threads.pop(&thread)) { + thread->join(); + delete thread; + } + + return dom->rval; +} + +rust_task_thread::rust_task_thread(int id, rust_kernel *owner) + : id(id), owner(owner) +{ +} + +void rust_task_thread::run() +{ + owner->dom->start_main_loop(id); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 70495d029bc13..ee5cf99ef5d4c 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -34,6 +34,9 @@ rust_handle : } }; +class rust_task_thread; + + /** * A global object shared by all thread domains. Most of the data structures * in this class are synchronized since they are accessed from multiple @@ -44,8 +47,6 @@ class rust_kernel : public rust_thread { rust_log _log; rust_srv *_srv; - rust_dom *dom; - /** * Task proxy objects are kernel owned handles to Rust objects. */ @@ -69,7 +70,11 @@ class rust_kernel : public rust_thread { rust_dom *create_domain(const char *name); void destroy_domain(); + array_list threads; + public: + rust_dom *dom; + lock_and_signal scheduler_lock; /** * Message queues are kernel objects and are associated with domains. @@ -105,7 +110,10 @@ class rust_kernel : public rust_thread { void *malloc(size_t size); void free(void *mem); + // TODO: this should go away inline rust_dom *get_domain() const { return dom; } + + int start_task_threads(int num_threads); }; inline void *operator new(size_t size, rust_kernel *kernel) { @@ -116,4 +124,15 @@ inline void *operator new(size_t size, rust_kernel &kernel) { return kernel.malloc(size); } + +class rust_task_thread : public rust_thread { + int id; + rust_kernel *owner; + +public: + rust_task_thread(int id, rust_kernel *owner); + + virtual void run(); +}; + #endif /* RUST_KERNEL_H */ diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 21c0f593f9ace..325bb560502c5 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -61,6 +61,7 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, gc_alloc_chain(0), dom(dom), cache(NULL), + kernel(dom->kernel), name(name), state(state), cond(NULL), @@ -134,7 +135,7 @@ void task_start_wrapper(spawn_args *a) LOG(task, task, "task exited with value %d", rval); { - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); // FIXME: the old exit glue does some magical argument copying // stuff. This is probably still needed. @@ -158,9 +159,9 @@ rust_task::start(uintptr_t spawnee_fn, LOGPTR(dom, "from spawnee", spawnee_fn); I(dom, stk->data != NULL); - I(dom, !dom->scheduler_lock.lock_held_by_current_thread()); - - scoped_lock with(dom->scheduler_lock); + I(dom, !kernel->scheduler_lock.lock_held_by_current_thread()); + + scoped_lock with(kernel->scheduler_lock); char *sp = (char *)rust_sp; @@ -412,7 +413,7 @@ rust_task::free(void *p, bool is_gc) void rust_task::transition(rust_task_list *src, rust_task_list *dst) { - I(dom, dom->scheduler_lock.lock_held_by_current_thread()); + I(dom, kernel->scheduler_lock.lock_held_by_current_thread()); DLOG(dom, task, "task %s " PTR " state change '%s' -> '%s' while in '%s'", name, (uintptr_t)this, src->name, dst->name, state->name); diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 3f9a0660300c6..62a725a98d5e9 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -22,6 +22,7 @@ rust_task : public maybe_proxy, rust_crate_cache *cache; // Fields known only to the runtime. + rust_kernel *kernel; const char *const name; rust_task_list *state; rust_cond *cond; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index a769051b7eb4d..ccb35958a8095 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -75,7 +75,7 @@ extern "C" CDECL rust_port* upcall_new_port(rust_task *task, size_t unit_sz) { LOG_UPCALL_ENTRY(task); rust_dom *dom = task->dom; - scoped_lock with(dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)", (uintptr_t) task, task->name, unit_sz); return new (dom) rust_port(task, unit_sz); @@ -84,7 +84,7 @@ upcall_new_port(rust_task *task, size_t unit_sz) { extern "C" CDECL void upcall_del_port(rust_task *task, rust_port *port) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "upcall del_port(0x%" PRIxPTR ")", (uintptr_t) port); I(task->dom, !port->ref_count); delete port; @@ -124,7 +124,7 @@ upcall_flush_chan(rust_task *task, rust_chan *chan) { extern "C" CDECL void upcall_del_chan(rust_task *task, rust_chan *chan) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "upcall del_chan(0x%" PRIxPTR ")", (uintptr_t) chan); @@ -166,7 +166,7 @@ extern "C" CDECL rust_chan * upcall_clone_chan(rust_task *task, maybe_proxy *target, rust_chan *chan) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); size_t unit_sz = chan->buffer.unit_sz; maybe_proxy *port = chan->port; rust_task *target_task = NULL; @@ -208,7 +208,7 @@ upcall_sleep(rust_task *task, size_t time_in_us) { extern "C" CDECL void upcall_send(rust_task *task, rust_chan *chan, void *sptr) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); chan->send(sptr); LOG(task, comm, "=== sent data ===>"); } @@ -217,7 +217,7 @@ extern "C" CDECL void upcall_recv(rust_task *task, uintptr_t *dptr, rust_port *port) { { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "port: 0x%" PRIxPTR ", dptr: 0x%" PRIxPTR ", size: 0x%" PRIxPTR ", chan_no: %d", @@ -255,7 +255,7 @@ upcall_fail(rust_task *task, extern "C" CDECL void upcall_kill(rust_task *task, maybe_proxy *target) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); if (target->is_proxy()) { notify_message:: send(notify_message::KILL, "kill", task->get_handle(), @@ -274,7 +274,7 @@ extern "C" CDECL void upcall_exit(rust_task *task) { { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, task, "task ref_count: %d", task->ref_count); A(task->dom, task->ref_count >= 0, "Task ref_count should not be negative on exit!"); @@ -287,7 +287,7 @@ upcall_exit(rust_task *task) { extern "C" CDECL uintptr_t upcall_malloc(rust_task *task, size_t nbytes, type_desc *td) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, mem, "upcall malloc(%" PRIdPTR ", 0x%" PRIxPTR ")" @@ -308,7 +308,7 @@ upcall_malloc(rust_task *task, size_t nbytes, type_desc *td) { extern "C" CDECL void upcall_free(rust_task *task, void* ptr, uintptr_t is_gc) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); rust_dom *dom = task->dom; DLOG(dom, mem, "upcall free(0x%" PRIxPTR ", is_gc=%" PRIdPTR ")", @@ -319,7 +319,7 @@ upcall_free(rust_task *task, void* ptr, uintptr_t is_gc) { extern "C" CDECL uintptr_t upcall_mark(rust_task *task, void* ptr) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); rust_dom *dom = task->dom; if (ptr) { @@ -350,7 +350,7 @@ rust_str *make_str(rust_task *task, char const *s, size_t fill) { extern "C" CDECL rust_str * upcall_new_str(rust_task *task, char const *s, size_t fill) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); return make_str(task, s, fill); } @@ -358,7 +358,7 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) { extern "C" CDECL rust_str * upcall_dup_str(rust_task *task, rust_str *str) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); return make_str(task, (char const *)str->data, str->fill); } @@ -366,7 +366,7 @@ upcall_dup_str(rust_task *task, rust_str *str) { extern "C" CDECL rust_vec * upcall_new_vec(rust_task *task, size_t fill, type_desc *td) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); rust_dom *dom = task->dom; DLOG(dom, mem, "upcall new_vec(%" PRIdPTR ")", fill); size_t alloc = next_power_of_two(sizeof(rust_vec) + fill); @@ -471,7 +471,7 @@ upcall_vec_append(rust_task *task, type_desc *t, type_desc *elem_t, rust_vec **dst_ptr, rust_vec *src, bool skip_null) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); rust_vec *dst = *dst_ptr; uintptr_t need_copy; size_t n_src_bytes = skip_null ? src->fill - 1 : src->fill; @@ -507,7 +507,7 @@ upcall_get_type_desc(rust_task *task, size_t n_descs, type_desc const **descs) { LOG_UPCALL_ENTRY(task); - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); LOG(task, cache, "upcall get_type_desc with size=%" PRIdPTR ", align=%" PRIdPTR ", %" PRIdPTR " descs", size, align, n_descs); @@ -521,7 +521,7 @@ extern "C" CDECL rust_task * upcall_new_task(rust_task *spawner, rust_vec *name) { // name is a rust string structure. LOG_UPCALL_ENTRY(spawner); - scoped_lock with(spawner->dom->scheduler_lock); + scoped_lock with(spawner->kernel->scheduler_lock); rust_dom *dom = spawner->dom; rust_task *task = dom->create_task(spawner, (const char *)name->data); return task; @@ -563,7 +563,7 @@ extern "C" CDECL void upcall_ivec_resize(rust_task *task, rust_ivec *v, size_t newsz) { - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); I(task->dom, !v->fill); size_t new_alloc = next_power_of_two(newsz); @@ -582,7 +582,7 @@ extern "C" CDECL void upcall_ivec_spill(rust_task *task, rust_ivec *v, size_t newsz) { - scoped_lock with(task->dom->scheduler_lock); + scoped_lock with(task->kernel->scheduler_lock); size_t new_alloc = next_power_of_two(newsz); rust_ivec_heap *heap_part = (rust_ivec_heap *) From 6834e262329943e3645da33fb7e87f4ea1f927cd Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 27 Jun 2011 19:15:03 -0700 Subject: [PATCH 4/9] Removed dom_owned, splitting things between task_owned and kernel_owned. Had to re-xfail a few tests brson recently un-xfailed. --- src/rt/circular_buffer.cpp | 17 +++-- src/rt/circular_buffer.h | 8 +- src/rt/memory.h | 45 ++++++----- src/rt/rust.cpp | 31 ++++---- src/rt/rust_builtin.cpp | 6 +- src/rt/rust_chan.cpp | 2 +- src/rt/rust_crate_cache.cpp | 4 +- src/rt/rust_dom.cpp | 68 +---------------- src/rt/rust_dom.h | 11 --- src/rt/rust_internal.h | 41 ++--------- src/rt/rust_kernel.h | 9 --- src/rt/rust_message.cpp | 7 +- src/rt/rust_port.cpp | 4 +- src/rt/rust_task.cpp | 86 +++++++++++++++++----- src/rt/rust_task.h | 39 +++++++++- src/rt/rust_task_list.h | 3 +- src/rt/rust_upcall.cpp | 7 +- src/rt/rust_util.h | 49 ++++++------ src/test/run-pass/child-outlives-parent.rs | 2 + src/test/run-pass/spawn-types.rs | 2 + src/test/run-pass/task-life-0.rs | 2 + 21 files changed, 217 insertions(+), 226 deletions(-) diff --git a/src/rt/circular_buffer.cpp b/src/rt/circular_buffer.cpp index ab98dfe34c4cd..0239e40f997d9 100644 --- a/src/rt/circular_buffer.cpp +++ b/src/rt/circular_buffer.cpp @@ -4,13 +4,14 @@ #include "rust_internal.h" -circular_buffer::circular_buffer(rust_dom *dom, size_t unit_sz) : - dom(dom), +circular_buffer::circular_buffer(rust_task *task, size_t unit_sz) : + dom(task->dom), + task(task), unit_sz(unit_sz), _buffer_sz(initial_size()), _next(0), _unread(0), - _buffer((uint8_t *)dom->malloc(_buffer_sz)) { + _buffer((uint8_t *)task->malloc(_buffer_sz)) { A(dom, unit_sz, "Unit size must be larger than zero."); @@ -26,7 +27,7 @@ circular_buffer::~circular_buffer() { I(dom, _buffer); W(dom, _unread == 0, "freeing circular_buffer with %d unread bytes", _unread); - dom->free(_buffer); + task->free(_buffer); } size_t @@ -141,9 +142,9 @@ circular_buffer::grow() { size_t new_buffer_sz = _buffer_sz * 2; I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE); DLOG(dom, mem, "circular_buffer is growing to %d bytes", new_buffer_sz); - void *new_buffer = dom->malloc(new_buffer_sz); + void *new_buffer = task->malloc(new_buffer_sz); transfer(new_buffer); - dom->free(_buffer); + task->free(_buffer); _buffer = (uint8_t *)new_buffer; _next = 0; _buffer_sz = new_buffer_sz; @@ -154,9 +155,9 @@ circular_buffer::shrink() { size_t new_buffer_sz = _buffer_sz / 2; I(dom, initial_size() <= new_buffer_sz); DLOG(dom, mem, "circular_buffer is shrinking to %d bytes", new_buffer_sz); - void *new_buffer = dom->malloc(new_buffer_sz); + void *new_buffer = task->malloc(new_buffer_sz); transfer(new_buffer); - dom->free(_buffer); + task->free(_buffer); _buffer = (uint8_t *)new_buffer; _next = 0; _buffer_sz = new_buffer_sz; diff --git a/src/rt/circular_buffer.h b/src/rt/circular_buffer.h index cdd0b03b09107..1e686ea6f1461 100644 --- a/src/rt/circular_buffer.h +++ b/src/rt/circular_buffer.h @@ -6,15 +6,17 @@ #define CIRCULAR_BUFFER_H class -circular_buffer : public dom_owned { +circular_buffer : public task_owned { static const size_t INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 8; static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24; -public: rust_dom *dom; + +public: + rust_task *task; // Size of the data unit in bytes. const size_t unit_sz; - circular_buffer(rust_dom *dom, size_t unit_sz); + circular_buffer(rust_task *task, size_t unit_sz); ~circular_buffer(); void transfer(void *dst); void enqueue(void *src); diff --git a/src/rt/memory.h b/src/rt/memory.h index 9196e28dd83b2..d5e5a6eb1a7cc 100644 --- a/src/rt/memory.h +++ b/src/rt/memory.h @@ -1,3 +1,4 @@ +// -*- c++ -*- #ifndef MEMORY_H #define MEMORY_H @@ -5,50 +6,54 @@ inline void *operator new(size_t size, void *mem) { return mem; } -inline void *operator new(size_t size, rust_dom *dom) { - return dom->malloc(size, memory_region::LOCAL); +inline void *operator new(size_t size, rust_kernel *kernel) { + return kernel->malloc(size); } -inline void *operator new[](size_t size, rust_dom *dom) { - return dom->malloc(size, memory_region::LOCAL); +inline void *operator new(size_t size, rust_task *task) { + return task->malloc(size, memory_region::LOCAL); } -inline void *operator new(size_t size, rust_dom &dom) { - return dom.malloc(size, memory_region::LOCAL); +inline void *operator new[](size_t size, rust_task *task) { + return task->malloc(size, memory_region::LOCAL); } -inline void *operator new[](size_t size, rust_dom &dom) { - return dom.malloc(size, memory_region::LOCAL); +inline void *operator new(size_t size, rust_task &task) { + return task.malloc(size, memory_region::LOCAL); } -inline void *operator new(size_t size, rust_dom *dom, +inline void *operator new[](size_t size, rust_task &task) { + return task.malloc(size, memory_region::LOCAL); +} + +inline void *operator new(size_t size, rust_task *task, memory_region::memory_region_type type) { - return dom->malloc(size, type); + return task->malloc(size, type); } -inline void *operator new[](size_t size, rust_dom *dom, +inline void *operator new[](size_t size, rust_task *task, memory_region::memory_region_type type) { - return dom->malloc(size, type); + return task->malloc(size, type); } -inline void *operator new(size_t size, rust_dom &dom, +inline void *operator new(size_t size, rust_task &task, memory_region::memory_region_type type) { - return dom.malloc(size, type); + return task.malloc(size, type); } -inline void *operator new[](size_t size, rust_dom &dom, +inline void *operator new[](size_t size, rust_task &task, memory_region::memory_region_type type) { - return dom.malloc(size, type); + return task.malloc(size, type); } -inline void operator delete(void *mem, rust_dom *dom) { - dom->free(mem, memory_region::LOCAL); +inline void operator delete(void *mem, rust_task *task) { + task->free(mem, memory_region::LOCAL); return; } -inline void operator delete(void *mem, rust_dom *dom, +inline void operator delete(void *mem, rust_task *task, memory_region::memory_region_type type) { - dom->free(mem, type); + task->free(mem, type); return; } diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 2a491b611509d..293d8562e4b3c 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -1,19 +1,21 @@ #include "rust_internal.h" struct -command_line_args : public dom_owned +command_line_args : public kernel_owned { - rust_dom *dom; + rust_kernel *kernel; + rust_task *task; int argc; char **argv; // vec[str] passed to rust_task::start. rust_vec *args; - command_line_args(rust_dom *dom, + command_line_args(rust_task *task, int sys_argc, char **sys_argv) - : dom(dom), + : kernel(task->kernel), + task(task), argc(sys_argc), argv(sys_argv), args(NULL) @@ -21,7 +23,7 @@ command_line_args : public dom_owned #if defined(__WIN32__) LPCWSTR cmdline = GetCommandLineW(); LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc); - dom->win32_require("CommandLineToArgvW", wargv != NULL); + task->dom->win32_require("CommandLineToArgvW", wargv != NULL); argv = (char **) dom->malloc(sizeof(char*) * argc); for (int i = 0; i < argc; ++i) { int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, @@ -36,14 +38,14 @@ command_line_args : public dom_owned #endif size_t vec_fill = sizeof(rust_str *) * argc; size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill); - void *mem = dom->malloc(vec_alloc); - args = new (mem) rust_vec(dom, vec_alloc, 0, NULL); + void *mem = kernel->malloc(vec_alloc); + args = new (mem) rust_vec(task->dom, vec_alloc, 0, NULL); rust_str **strs = (rust_str**) &args->data[0]; for (int i = 0; i < argc; ++i) { size_t str_fill = strlen(argv[i]) + 1; size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill); - mem = dom->malloc(str_alloc); - strs[i] = new (mem) rust_str(dom, str_alloc, str_fill, + mem = kernel->malloc(str_alloc); + strs[i] = new (mem) rust_str(task->dom, str_alloc, str_fill, (uint8_t const *)argv[i]); } args->fill = vec_fill; @@ -58,15 +60,15 @@ command_line_args : public dom_owned // Drop the args we've had pinned here. rust_str **strs = (rust_str**) &args->data[0]; for (int i = 0; i < argc; ++i) - dom->free(strs[i]); - dom->free(args); + kernel->free(strs[i]); + kernel->free(args); } #ifdef __WIN32__ for (int i = 0; i < argc; ++i) { - dom->free(argv[i]); + task->free(argv[i]); } - dom->free(argv); + task->free(argv); #endif } }; @@ -97,7 +99,8 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { rust_kernel *kernel = new rust_kernel(srv); kernel->start(); rust_dom *dom = kernel->get_domain(); - command_line_args *args = new (dom) command_line_args(dom, argc, argv); + command_line_args *args + = new (kernel) command_line_args(dom->root_task, argc, argv); DLOG(dom, dom, "startup: %d args in 0x%" PRIxPTR, args->argc, (uintptr_t)args->args); diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 2a724ee179134..76455d0ca9980 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -42,7 +42,7 @@ last_os_error(rust_task *task) { #endif size_t fill = strlen(buf) + 1; size_t alloc = next_power_of_two(sizeof(rust_str) + fill); - void *mem = dom->malloc(alloc, memory_region::LOCAL); + void *mem = task->malloc(alloc, memory_region::LOCAL); if (!mem) { task->fail(1); return NULL; @@ -73,7 +73,7 @@ rust_getcwd(rust_task *task) { size_t fill = strlen(cbuf) + 1; size_t alloc = next_power_of_two(sizeof(rust_str) + fill); - void *mem = dom->malloc(alloc, memory_region::LOCAL); + void *mem = task->malloc(alloc, memory_region::LOCAL); if (!mem) { task->fail(1); return NULL; @@ -200,7 +200,7 @@ vec_alloc_with_data(rust_task *task, { rust_dom *dom = task->dom; size_t alloc = next_power_of_two(sizeof(rust_vec) + (n_elts * elt_size)); - void *mem = dom->malloc(alloc, memory_region::LOCAL); + void *mem = task->malloc(alloc, memory_region::LOCAL); if (!mem) return NULL; return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d); } diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp index cc03c227acda9..bf75c89057ba2 100644 --- a/src/rt/rust_chan.cpp +++ b/src/rt/rust_chan.cpp @@ -9,7 +9,7 @@ rust_chan::rust_chan(rust_task *task, size_t unit_sz) : task(task), port(port), - buffer(task->dom, unit_sz) { + buffer(task, unit_sz) { ++task->ref_count; if (port) { associate(port); diff --git a/src/rt/rust_crate_cache.cpp b/src/rt/rust_crate_cache.cpp index 1f66e0e0084e1..70509dcae95fe 100644 --- a/src/rt/rust_crate_cache.cpp +++ b/src/rt/rust_crate_cache.cpp @@ -16,7 +16,7 @@ rust_crate_cache::get_type_desc(size_t size, return td; } DLOG(dom, cache, "rust_crate_cache::get_type_desc miss"); - td = (type_desc*) dom->malloc(sizeof(type_desc) + keysz); + td = (type_desc*) dom->kernel->malloc(sizeof(type_desc) + keysz); if (!td) return NULL; // By convention, desc 0 is the root descriptor. @@ -53,7 +53,7 @@ rust_crate_cache::flush() { type_desc *d = type_descs; HASH_DEL(type_descs, d); DLOG(dom, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d); - dom->free(d); + dom->kernel->free(d); } } diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index 65ccf158b64a3..d89cb181fb8ba 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -10,8 +10,6 @@ rust_dom::rust_dom(rust_kernel *kernel, _log(srv, this), log_lvl(log_note), srv(srv), - local_region(&srv->local_region), - synchronized_region(&srv->synchronized_region), name(name), newborn_tasks(this, "newborn"), running_tasks(this, "running"), @@ -36,6 +34,7 @@ rust_dom::rust_dom(rust_kernel *kernel, rust_dom::~rust_dom() { DLOG(this, dom, "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this); + newborn_tasks.delete_all(); running_tasks.delete_all(); blocked_tasks.delete_all(); @@ -75,69 +74,6 @@ rust_dom::fail() { rval = 1; } -void * -rust_dom::malloc(size_t size) { - return malloc(size, memory_region::LOCAL); -} - -void * -rust_dom::malloc(size_t size, memory_region::memory_region_type type) { - if (type == memory_region::LOCAL) { - return local_region.malloc(size); - } else if (type == memory_region::SYNCHRONIZED) { - return synchronized_region.malloc(size); - } - I(this, false); - return NULL; -} - -void * -rust_dom::calloc(size_t size) { - return calloc(size, memory_region::LOCAL); -} - -void * -rust_dom::calloc(size_t size, memory_region::memory_region_type type) { - if (type == memory_region::LOCAL) { - return local_region.calloc(size); - } else if (type == memory_region::SYNCHRONIZED) { - return synchronized_region.calloc(size); - } - return NULL; -} - -void * -rust_dom::realloc(void *mem, size_t size) { - return realloc(mem, size, memory_region::LOCAL); -} - -void * -rust_dom::realloc(void *mem, size_t size, - memory_region::memory_region_type type) { - if (type == memory_region::LOCAL) { - return local_region.realloc(mem, size); - } else if (type == memory_region::SYNCHRONIZED) { - return synchronized_region.realloc(mem, size); - } - return NULL; -} - -void -rust_dom::free(void *mem) { - free(mem, memory_region::LOCAL); -} - -void -rust_dom::free(void *mem, memory_region::memory_region_type type) { - DLOG(this, mem, "rust_dom::free(0x%" PRIxPTR ")", mem); - if (type == memory_region::LOCAL) { - local_region.free(mem); - } else if (type == memory_region::SYNCHRONIZED) { - synchronized_region.free(mem); - } - return; -} - #ifdef __WIN32__ void rust_dom::win32_require(LPCTSTR fn, BOOL ok) { @@ -372,7 +308,7 @@ rust_dom::get_cache() { rust_task * rust_dom::create_task(rust_task *spawner, const char *name) { rust_task *task = - new (this) rust_task (this, &newborn_tasks, spawner, name); + new (this->kernel) rust_task (this, &newborn_tasks, spawner, name); DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s", task, spawner ? spawner->name : "null", name); newborn_tasks.append(task); diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h index dfc0960a9ea90..b936a0e580aed 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_dom.h @@ -35,8 +35,6 @@ struct rust_dom : public kernel_owned, rc_base rust_log _log; uint32_t log_lvl; rust_srv *srv; - memory_region local_region; - memory_region synchronized_region; const char *const name; rust_task_list newborn_tasks; @@ -74,15 +72,6 @@ struct rust_dom : public kernel_owned, rc_base void log(rust_task *task, uint32_t level, char const *fmt, ...); rust_log & get_log(); void fail(); - void *malloc(size_t size); - void *malloc(size_t size, memory_region::memory_region_type type); - void *calloc(size_t size); - void *calloc(size_t size, memory_region::memory_region_type type); - void *realloc(void *mem, size_t size); - void *realloc(void *mem, size_t size, - memory_region::memory_region_type type); - void free(void *mem); - void free(void *mem, memory_region::memory_region_type type); void drain_incoming_message_queue(bool process); diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index cc494a261486a..ac201fc799ccb 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -115,15 +115,9 @@ template struct rc_base { ~rc_base(); }; -template struct dom_owned { - void operator delete(void *ptr) { - ((T *)ptr)->dom->free(ptr); - } -}; - template struct task_owned { void operator delete(void *ptr) { - ((T *)ptr)->task->dom->free(ptr); + ((T *)ptr)->task->free(ptr); } }; @@ -148,14 +142,14 @@ struct rust_cond { }; // Helper class used regularly elsewhere. -template class ptr_vec : public dom_owned > { +template class ptr_vec : public task_owned > { static const size_t INIT_SIZE = 8; - rust_dom *dom; + rust_task *task; size_t alloc; size_t fill; T **data; public: - ptr_vec(rust_dom *dom); + ptr_vec(rust_task *task); ~ptr_vec(); size_t length() { @@ -181,7 +175,6 @@ template class ptr_vec : public dom_owned > { #include "rust_kernel.h" #include "rust_message.h" #include "rust_dom.h" -#include "memory.h" struct rust_timer { // FIXME: This will probably eventually need replacement @@ -250,35 +243,11 @@ rust_alarm typedef ptr_vec rust_wait_queue; -struct stk_seg { - unsigned int valgrind_id; - uintptr_t limit; - uint8_t data[]; -}; - -struct frame_glue_fns { - uintptr_t mark_glue_off; - uintptr_t drop_glue_off; - uintptr_t reloc_glue_off; -}; - -struct gc_alloc { - gc_alloc *prev; - gc_alloc *next; - uintptr_t ctrl_word; - uint8_t data[]; - bool mark() { - if (ctrl_word & 1) - return false; - ctrl_word |= 1; - return true; - } -}; - #include "circular_buffer.h" #include "rust_task.h" #include "rust_chan.h" #include "rust_port.h" +#include "memory.h" // // Local Variables: diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index ee5cf99ef5d4c..5e03d8072d64f 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -116,15 +116,6 @@ class rust_kernel : public rust_thread { int start_task_threads(int num_threads); }; -inline void *operator new(size_t size, rust_kernel *kernel) { - return kernel->malloc(size); -} - -inline void *operator new(size_t size, rust_kernel &kernel) { - return kernel.malloc(size); -} - - class rust_task_thread : public rust_thread { int id; rust_kernel *owner; diff --git a/src/rt/rust_message.cpp b/src/rt/rust_message.cpp index 19a1d8a367e4e..6d1b7c528d282 100644 --- a/src/rt/rust_message.cpp +++ b/src/rt/rust_message.cpp @@ -109,9 +109,10 @@ void data_message::kernel_process() { } -rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) : - region (srv, true), kernel(kernel), - dom_handle(NULL) { +rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) + : region(srv, true), + kernel(kernel), + dom_handle(NULL) { // Nop. } diff --git a/src/rt/rust_port.cpp b/src/rt/rust_port.cpp index 57d0b21683650..a2bd3b34c38dc 100644 --- a/src/rt/rust_port.cpp +++ b/src/rt/rust_port.cpp @@ -3,14 +3,14 @@ rust_port::rust_port(rust_task *task, size_t unit_sz) : maybe_proxy(this), task(task), - unit_sz(unit_sz), writers(task->dom), chans(task->dom) { + unit_sz(unit_sz), writers(task), chans(task) { LOG(task, comm, "new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%" PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this); // Allocate a remote channel, for remote channel data. - remote_channel = new (task->dom) rust_chan(task, this, unit_sz); + remote_channel = new (task) rust_chan(task, this, unit_sz); } rust_port::~rust_port() { diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 325bb560502c5..52987c68d6462 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -20,16 +20,16 @@ static size_t const min_stk_bytes = 0x100000; // Task stack segments. Heap allocated and chained together. static stk_seg* -new_stk(rust_dom *dom, size_t minsz) +new_stk(rust_task *task, size_t minsz) { if (minsz < min_stk_bytes) minsz = min_stk_bytes; size_t sz = sizeof(stk_seg) + minsz; - stk_seg *stk = (stk_seg *)dom->malloc(sz); - LOGPTR(dom, "new stk", (uintptr_t)stk); + stk_seg *stk = (stk_seg *)task->malloc(sz); + LOGPTR(task->dom, "new stk", (uintptr_t)stk); memset(stk, 0, sizeof(stk_seg)); stk->limit = (uintptr_t) &stk->data[minsz]; - LOGPTR(dom, "stk limit", stk->limit); + LOGPTR(task->dom, "stk limit", stk->limit); stk->valgrind_id = VALGRIND_STACK_REGISTER(&stk->data[0], &stk->data[minsz]); @@ -37,11 +37,11 @@ new_stk(rust_dom *dom, size_t minsz) } static void -del_stk(rust_dom *dom, stk_seg *stk) +del_stk(rust_task *task, stk_seg *stk) { VALGRIND_STACK_DEREGISTER(stk->valgrind_id); - LOGPTR(dom, "freeing stk segment", (uintptr_t)stk); - dom->free(stk); + LOGPTR(task->dom, "freeing stk segment", (uintptr_t)stk); + task->free(stk); } // Tasks @@ -55,9 +55,9 @@ size_t const callee_save_fp = 0; rust_task::rust_task(rust_dom *dom, rust_task_list *state, rust_task *spawner, const char *name) : maybe_proxy(this), - stk(new_stk(dom, 0)), + stk(NULL), runtime_sp(0), - rust_sp(stk->limit), + rust_sp(NULL), gc_alloc_chain(0), dom(dom), cache(NULL), @@ -69,13 +69,17 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, supervisor(spawner), list_index(-1), rendezvous_ptr(0), - alarm(this), handle(NULL), - active(false) + active(false), + local_region(&dom->srv->local_region), + synchronized_region(&dom->srv->synchronized_region) { LOGPTR(dom, "new task", (uintptr_t)this); DLOG(dom, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this); + stk = new_stk(this, 0); + rust_sp = stk->limit; + if (spawner == NULL) { ref_count = 0; } @@ -111,7 +115,7 @@ rust_task::~rust_task() I(dom, ref_count == 0 || (ref_count == 1 && this == dom->root_task)); - del_stk(dom, stk); + del_stk(this, stk); } extern "C" void rust_new_exit_task_glue(); @@ -352,7 +356,7 @@ rust_task::malloc(size_t sz, type_desc *td) if (td) { sz += sizeof(gc_alloc); } - void *mem = dom->malloc(sz); + void *mem = malloc(sz, memory_region::LOCAL); if (!mem) return mem; if (td) { @@ -379,7 +383,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc) gc_alloc *gcm = (gc_alloc*)(((char *)data) - sizeof(gc_alloc)); unlink_gc(gcm); sz += sizeof(gc_alloc); - gcm = (gc_alloc*) dom->realloc((void*)gcm, sz); + gcm = (gc_alloc*) realloc((void*)gcm, sz, memory_region::LOCAL); DLOG(dom, task, "task %s @0x%" PRIxPTR " reallocated %d GC bytes = 0x%" PRIxPTR, name, (uintptr_t)this, sz, gcm); @@ -388,7 +392,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc) link_gc(gcm); data = (void*) &(gcm->data); } else { - data = dom->realloc(data, sz); + data = realloc(data, sz, memory_region::LOCAL); } return data; } @@ -405,9 +409,9 @@ rust_task::free(void *p, bool is_gc) DLOG(dom, mem, "task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR, name, (uintptr_t)this, gcm); - dom->free(gcm); + free(gcm, memory_region::LOCAL); } else { - dom->free(p); + free(p, memory_region::LOCAL); } } @@ -492,6 +496,54 @@ bool rust_task::can_schedule() return yield_timer.has_timed_out() && !active; } +void * +rust_task::malloc(size_t size, memory_region::memory_region_type type) { + if (type == memory_region::LOCAL) { + return local_region.malloc(size); + } else if (type == memory_region::SYNCHRONIZED) { + return synchronized_region.malloc(size); + } + I(dom, false); + return NULL; +} + +void * +rust_task::calloc(size_t size) { + return calloc(size, memory_region::LOCAL); +} + +void * +rust_task::calloc(size_t size, memory_region::memory_region_type type) { + if (type == memory_region::LOCAL) { + return local_region.calloc(size); + } else if (type == memory_region::SYNCHRONIZED) { + return synchronized_region.calloc(size); + } + return NULL; +} + +void * +rust_task::realloc(void *mem, size_t size, + memory_region::memory_region_type type) { + if (type == memory_region::LOCAL) { + return local_region.realloc(mem, size); + } else if (type == memory_region::SYNCHRONIZED) { + return synchronized_region.realloc(mem, size); + } + return NULL; +} + +void +rust_task::free(void *mem, memory_region::memory_region_type type) { + DLOG(dom, mem, "rust_task::free(0x%" PRIxPTR ")", mem); + if (type == memory_region::LOCAL) { + local_region.free(mem); + } else if (type == memory_region::SYNCHRONIZED) { + synchronized_region.free(mem); + } + return; +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 62a725a98d5e9..5e61306af2e01 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -9,9 +9,34 @@ #include "context.h" +struct stk_seg { + unsigned int valgrind_id; + uintptr_t limit; + uint8_t data[]; +}; + +struct frame_glue_fns { + uintptr_t mark_glue_off; + uintptr_t drop_glue_off; + uintptr_t reloc_glue_off; +}; + +struct gc_alloc { + gc_alloc *prev; + gc_alloc *next; + uintptr_t ctrl_word; + uint8_t data[]; + bool mark() { + if (ctrl_word & 1) + return false; + ctrl_word |= 1; + return true; + } +}; + struct rust_task : public maybe_proxy, - public dom_owned + public kernel_owned { // Fields known to the compiler. stk_seg *stk; @@ -46,8 +71,6 @@ rust_task : public maybe_proxy, // List of tasks waiting for this task to finish. array_list *> tasks_waiting_to_join; - rust_alarm alarm; - rust_handle *handle; context ctx; @@ -56,6 +79,9 @@ rust_task : public maybe_proxy, // or is about to run this task. volatile bool active; + memory_region local_region; + memory_region synchronized_region; + // Only a pointer to 'name' is kept, so it must live as long as this task. rust_task(rust_dom *dom, rust_task_list *state, @@ -118,6 +144,13 @@ rust_task : public maybe_proxy, rust_crate_cache * get_crate_cache(); bool can_schedule(); + + void *malloc(size_t size, memory_region::memory_region_type type); + void *calloc(size_t size); + void *calloc(size_t size, memory_region::memory_region_type type); + void *realloc(void *mem, size_t size, + memory_region::memory_region_type type); + void free(void *mem, memory_region::memory_region_type type); }; // diff --git a/src/rt/rust_task_list.h b/src/rt/rust_task_list.h index b1fba75029d45..479f9e936fbc8 100644 --- a/src/rt/rust_task_list.h +++ b/src/rt/rust_task_list.h @@ -1,3 +1,4 @@ +// -*- c++-mode -*- #ifndef RUST_TASK_LIST_H #define RUST_TASK_LIST_H @@ -5,7 +6,7 @@ * Used to indicate the state of a rust task. */ class rust_task_list : public indexed_list, - public dom_owned { + public kernel_owned { public: rust_dom *dom; const char* name; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index ccb35958a8095..ce349b18e9d31 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -74,11 +74,10 @@ upcall_trace_str(rust_task *task, char const *c) { extern "C" CDECL rust_port* upcall_new_port(rust_task *task, size_t unit_sz) { LOG_UPCALL_ENTRY(task); - rust_dom *dom = task->dom; scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)", (uintptr_t) task, task->name, unit_sz); - return new (dom) rust_port(task, unit_sz); + return new (task) rust_port(task, unit_sz); } extern "C" CDECL void @@ -101,7 +100,7 @@ upcall_new_chan(rust_task *task, rust_port *port) { "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")", (uintptr_t) task, task->name, port); I(dom, port); - return new (dom) rust_chan(task, port, port->unit_sz); + return new (task) rust_chan(task, port, port->unit_sz); } /** @@ -181,7 +180,7 @@ upcall_clone_chan(rust_task *task, maybe_proxy *target, port = proxy; target_task = target->as_proxy()->handle()->referent(); } - return new (target_task->dom) rust_chan(target_task, port, unit_sz); + return new (target_task) rust_chan(target_task, port, unit_sz); } extern "C" CDECL void diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index fe3c245996654..260f7eb9d5df3 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -1,6 +1,8 @@ #ifndef RUST_UTIL_H #define RUST_UTIL_H +#include "rust_task.h" + // Reference counted objects template @@ -17,30 +19,30 @@ rc_base::~rc_base() // Utility type: pointer-vector. template -ptr_vec::ptr_vec(rust_dom *dom) : - dom(dom), +ptr_vec::ptr_vec(rust_task *task) : + task(task), alloc(INIT_SIZE), fill(0), - data(new (dom) T*[alloc]) + data(new (task) T*[alloc]) { - I(dom, data); - DLOG(dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR, + I(task->dom, data); + DLOG(task->dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR, (uintptr_t)data, (uintptr_t)this); } template ptr_vec::~ptr_vec() { - I(dom, data); - DLOG(dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR, + I(task->dom, data); + DLOG(task->dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR, (uintptr_t)this, (uintptr_t)data); - I(dom, fill == 0); - dom->free(data); + I(task->dom, fill == 0); + task->free(data); } template T *& ptr_vec::operator[](size_t offset) { - I(dom, data[offset]->idx == offset); + I(task->dom, data[offset]->idx == offset); return data[offset]; } @@ -48,14 +50,14 @@ template void ptr_vec::push(T *p) { - I(dom, data); - I(dom, fill <= alloc); + I(task->dom, data); + I(task->dom, fill <= alloc); if (fill == alloc) { alloc *= 2; - data = (T **)dom->realloc(data, alloc * sizeof(T*)); - I(dom, data); + data = (T **)task->realloc(data, alloc * sizeof(T*)); + I(task->dom, data); } - I(dom, fill < alloc); + I(task->dom, fill < alloc); p->idx = fill; data[fill++] = p; } @@ -78,13 +80,13 @@ template void ptr_vec::trim(size_t sz) { - I(dom, data); + I(task->dom, data); if (sz <= (alloc / 4) && (alloc / 2) >= INIT_SIZE) { alloc /= 2; - I(dom, alloc >= fill); - data = (T **)dom->realloc(data, alloc * sizeof(T*)); - I(dom, data); + I(task->dom, alloc >= fill); + data = (T **)task->realloc(data, alloc * sizeof(T*)); + I(task->dom, data); } } @@ -93,9 +95,9 @@ void ptr_vec::swap_delete(T *item) { /* Swap the endpoint into i and decr fill. */ - I(dom, data); - I(dom, fill > 0); - I(dom, item->idx < fill); + I(task->dom, data); + I(task->dom, fill > 0); + I(task->dom, item->idx < fill); fill--; if (fill > 0) { T *subst = data[fill]; @@ -155,7 +157,8 @@ isaac_init(rust_dom *dom, randctx *rctx) } else { int fd = open("/dev/urandom", O_RDONLY); I(dom, fd > 0); - I(dom, read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl)) + I(dom, + read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl)) == sizeof(rctx->randrsl)); I(dom, close(fd) == 0); } diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs index 988172ba6ad6c..9cd3b67821b93 100644 --- a/src/test/run-pass/child-outlives-parent.rs +++ b/src/test/run-pass/child-outlives-parent.rs @@ -2,6 +2,8 @@ // xfail-stage0 +// xfail-stage1 +// xfail-stage2 // Reported as issue #126, child leaks the string. fn child2(str s) { } diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index 4bbeb3c064f11..0051b2ba14dbd 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -5,6 +5,8 @@ */ // xfail-stage0 +// xfail-stage1 +// xfail-stage2 use std; diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs index 324572344a4dc..726dfa261e0a2 100644 --- a/src/test/run-pass/task-life-0.rs +++ b/src/test/run-pass/task-life-0.rs @@ -1,4 +1,6 @@ // xfail-stage0 +// xfail-stage1 +// xfail-stage2 fn main() -> () { spawn child("Hello"); } From 2624bcd4a14a77cb5a37c398b9b4e56900c300c4 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 11:12:00 -0700 Subject: [PATCH 5/9] Fixed Win32 compile errors. --- src/rt/rust.cpp | 12 ++++++------ src/rt/rust_task.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 293d8562e4b3c..19f114d29a925 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -24,15 +24,15 @@ command_line_args : public kernel_owned LPCWSTR cmdline = GetCommandLineW(); LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc); task->dom->win32_require("CommandLineToArgvW", wargv != NULL); - argv = (char **) dom->malloc(sizeof(char*) * argc); + argv = (char **) kernel->malloc(sizeof(char*) * argc); for (int i = 0; i < argc; ++i) { int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL); - dom->win32_require("WideCharToMultiByte(0)", n_chars != 0); - argv[i] = (char *) dom->malloc(n_chars); + task->dom->win32_require("WideCharToMultiByte(0)", n_chars != 0); + argv[i] = (char *) kernel->malloc(n_chars); n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n_chars, NULL, NULL); - dom->win32_require("WideCharToMultiByte(1)", n_chars != 0); + task->dom->win32_require("WideCharToMultiByte(1)", n_chars != 0); } LocalFree(wargv); #endif @@ -66,9 +66,9 @@ command_line_args : public kernel_owned #ifdef __WIN32__ for (int i = 0; i < argc; ++i) { - task->free(argv[i]); + kernel->free(argv[i]); } - task->free(argv); + kernel->free(argv); #endif } }; diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 52987c68d6462..385e084cd6cc5 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -57,7 +57,7 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, maybe_proxy(this), stk(NULL), runtime_sp(0), - rust_sp(NULL), + rust_sp(0), gc_alloc_chain(0), dom(dom), cache(NULL), From bbbf531126d3bfb22e6edf9b65668bd90bd86ccd Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 11:34:20 -0700 Subject: [PATCH 6/9] Moved win32_require to the kernel. --- src/rt/rust.cpp | 6 +++--- src/rt/rust_dom.cpp | 19 ------------------- src/rt/rust_dom.h | 4 ---- src/rt/rust_kernel.cpp | 19 +++++++++++++++++++ src/rt/rust_kernel.h | 6 +++++- src/rt/rust_timer.cpp | 7 ++++--- src/rt/rust_util.h | 6 +++--- 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 19f114d29a925..c2a56d993d8c7 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -23,16 +23,16 @@ command_line_args : public kernel_owned #if defined(__WIN32__) LPCWSTR cmdline = GetCommandLineW(); LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc); - task->dom->win32_require("CommandLineToArgvW", wargv != NULL); + kernel->win32_require("CommandLineToArgvW", wargv != NULL); argv = (char **) kernel->malloc(sizeof(char*) * argc); for (int i = 0; i < argc; ++i) { int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, NULL, 0, NULL, NULL); - task->dom->win32_require("WideCharToMultiByte(0)", n_chars != 0); + kernel->win32_require("WideCharToMultiByte(0)", n_chars != 0); argv[i] = (char *) kernel->malloc(n_chars); n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i], n_chars, NULL, NULL); - task->dom->win32_require("WideCharToMultiByte(1)", n_chars != 0); + kernel->win32_require("WideCharToMultiByte(1)", n_chars != 0); } LocalFree(wargv); #endif diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_dom.cpp index d89cb181fb8ba..ac3c3a82a4065 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_dom.cpp @@ -74,25 +74,6 @@ rust_dom::fail() { rval = 1; } -#ifdef __WIN32__ -void -rust_dom::win32_require(LPCTSTR fn, BOOL ok) { - if (!ok) { - LPTSTR buf; - DWORD err = GetLastError(); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &buf, 0, NULL ); - DLOG_ERR(this, dom, "%s failed with error %ld: %s", fn, err, buf); - LocalFree((HLOCAL)buf); - I(this, ok); - } -} -#endif - size_t rust_dom::number_of_live_tasks() { return running_tasks.length() + blocked_tasks.length(); diff --git a/src/rt/rust_dom.h b/src/rt/rust_dom.h index b936a0e580aed..04a42b5fb01f9 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_dom.h @@ -75,10 +75,6 @@ struct rust_dom : public kernel_owned, rc_base void drain_incoming_message_queue(bool process); -#ifdef __WIN32__ - void win32_require(LPCTSTR fn, BOOL ok); -#endif - rust_crate_cache *get_cache(); size_t number_of_live_tasks(); diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 5e495b8c822b2..ee709fb191fe2 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -245,6 +245,25 @@ int rust_kernel::start_task_threads(int num_threads) return dom->rval; } +#ifdef __WIN32__ +void +rust_kernel::win32_require(LPCTSTR fn, BOOL ok) { + if (!ok) { + LPTSTR buf; + DWORD err = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buf, 0, NULL ); + DLOG_ERR(dom, dom, "%s failed with error %ld: %s", fn, err, buf); + LocalFree((HLOCAL)buf); + I(dom, ok); + } +} +#endif + rust_task_thread::rust_task_thread(int id, rust_kernel *owner) : id(id), owner(owner) { diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 5e03d8072d64f..b3befab28d2ac 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -110,10 +110,14 @@ class rust_kernel : public rust_thread { void *malloc(size_t size); void free(void *mem); - // TODO: this should go away + // FIXME: this should go away inline rust_dom *get_domain() const { return dom; } int start_task_threads(int num_threads); + +#ifdef __WIN32__ + void win32_require(LPCTSTR fn, BOOL ok); +#endif }; class rust_task_thread : public rust_thread { diff --git a/src/rt/rust_timer.cpp b/src/rt/rust_timer.cpp index 79cb1615bbc3f..2d732a2359169 100644 --- a/src/rt/rust_timer.cpp +++ b/src/rt/rust_timer.cpp @@ -57,7 +57,7 @@ rust_timer::rust_timer(rust_dom *dom) : DLOG(dom, timer, "creating timer for domain 0x%" PRIxPTR, dom); #if defined(__WIN32__) thread = CreateThread(NULL, 0, timer_loop, this, 0, NULL); - dom->win32_require("CreateThread", thread != NULL); + dom->kernel->win32_require("CreateThread", thread != NULL); if (RUNNING_ON_VALGRIND) Sleep(10); #else @@ -70,8 +70,9 @@ rust_timer::rust_timer(rust_dom *dom) : rust_timer::~rust_timer() { exit_flag = 1; #if defined(__WIN32__) - dom->win32_require("WaitForSingleObject", - WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0); + dom->kernel->win32_require("WaitForSingleObject", + WaitForSingleObject(thread, INFINITE) == + WAIT_OBJECT_0); #else pthread_join(thread, NULL); #endif diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 260f7eb9d5df3..bd888c108f134 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -134,15 +134,15 @@ isaac_init(rust_dom *dom, randctx *rctx) #ifdef __WIN32__ { HCRYPTPROV hProv; - dom->win32_require + dom->kernel->win32_require (_T("CryptAcquireContext"), CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); - dom->win32_require + dom->kernel->win32_require (_T("CryptGenRandom"), CryptGenRandom(hProv, sizeof(rctx->randrsl), (BYTE*)(&rctx->randrsl))); - dom->win32_require + dom->kernel->win32_require (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); } From 76f9bf1fdafe4b69a38e79cdcd07b266fc21fb2f Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 12:15:41 -0700 Subject: [PATCH 7/9] Renamed what's left of rust_dom to rust_scheduler --- mk/rt.mk | 4 +- src/rt/circular_buffer.cpp | 70 ++++++------ src/rt/circular_buffer.h | 2 +- src/rt/rust.cpp | 16 +-- src/rt/rust_builtin.cpp | 20 ++-- src/rt/rust_chan.cpp | 12 +- src/rt/rust_crate_cache.cpp | 20 ++-- src/rt/rust_internal.h | 8 +- src/rt/rust_kernel.cpp | 73 ++++++------ src/rt/rust_kernel.h | 17 +-- src/rt/rust_log.cpp | 10 +- src/rt/rust_log.h | 27 ++--- src/rt/rust_message.cpp | 2 +- src/rt/rust_message.h | 10 +- src/rt/{rust_dom.cpp => rust_scheduler.cpp} | 28 ++--- src/rt/{rust_dom.h => rust_scheduler.h} | 20 ++-- src/rt/rust_task.cpp | 120 ++++++++------------ src/rt/rust_task.h | 8 +- src/rt/rust_task_list.cpp | 8 +- src/rt/rust_task_list.h | 6 +- src/rt/rust_timer.cpp | 22 ++-- src/rt/rust_upcall.cpp | 68 +++++------ src/rt/rust_util.h | 53 ++++----- 23 files changed, 303 insertions(+), 321 deletions(-) rename src/rt/{rust_dom.cpp => rust_scheduler.cpp} (92%) rename src/rt/{rust_dom.h => rust_scheduler.h} (85%) diff --git a/mk/rt.mk b/mk/rt.mk index b4cdefd996ce5..bd935d660ff8e 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -10,7 +10,7 @@ RUNTIME_CS := rt/sync/timer.cpp \ rt/rust_run_program.cpp \ rt/rust_crate_cache.cpp \ rt/rust_comm.cpp \ - rt/rust_dom.cpp \ + rt/rust_scheduler.cpp \ rt/rust_task.cpp \ rt/rust_task_list.cpp \ rt/rust_proxy.cpp \ @@ -37,7 +37,7 @@ RUNTIME_HDR := rt/globals.h \ rt/rust_util.h \ rt/rust_chan.h \ rt/rust_port.h \ - rt/rust_dom.h \ + rt/rust_scheduler.h \ rt/rust_task.h \ rt/rust_task_list.h \ rt/rust_proxy.h \ diff --git a/src/rt/circular_buffer.cpp b/src/rt/circular_buffer.cpp index 0239e40f997d9..8c0067ff002e2 100644 --- a/src/rt/circular_buffer.cpp +++ b/src/rt/circular_buffer.cpp @@ -5,7 +5,7 @@ #include "rust_internal.h" circular_buffer::circular_buffer(rust_task *task, size_t unit_sz) : - dom(task->dom), + sched(task->sched), task(task), unit_sz(unit_sz), _buffer_sz(initial_size()), @@ -13,26 +13,26 @@ circular_buffer::circular_buffer(rust_task *task, size_t unit_sz) : _unread(0), _buffer((uint8_t *)task->malloc(_buffer_sz)) { - A(dom, unit_sz, "Unit size must be larger than zero."); + A(sched, unit_sz, "Unit size must be larger than zero."); - DLOG(dom, mem, "new circular_buffer(buffer_sz=%d, unread=%d)" + DLOG(sched, mem, "new circular_buffer(buffer_sz=%d, unread=%d)" "-> circular_buffer=0x%" PRIxPTR, _buffer_sz, _unread, this); - A(dom, _buffer, "Failed to allocate buffer."); + A(sched, _buffer, "Failed to allocate buffer."); } circular_buffer::~circular_buffer() { - DLOG(dom, mem, "~circular_buffer 0x%" PRIxPTR, this); - I(dom, _buffer); - W(dom, _unread == 0, + DLOG(sched, mem, "~circular_buffer 0x%" PRIxPTR, this); + I(sched, _buffer); + W(sched, _unread == 0, "freeing circular_buffer with %d unread bytes", _unread); task->free(_buffer); } size_t circular_buffer::initial_size() { - I(dom, unit_sz > 0); + I(sched, unit_sz > 0); return INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS * unit_sz; } @@ -41,8 +41,8 @@ circular_buffer::initial_size() { */ void circular_buffer::transfer(void *dst) { - I(dom, dst); - I(dom, _unread <= _buffer_sz); + I(sched, dst); + I(sched, _unread <= _buffer_sz); uint8_t *ptr = (uint8_t *) dst; @@ -54,13 +54,13 @@ circular_buffer::transfer(void *dst) { } else { head_sz = _buffer_sz - _next; } - I(dom, _next + head_sz <= _buffer_sz); + I(sched, _next + head_sz <= _buffer_sz); memcpy(ptr, _buffer + _next, head_sz); // Then copy any other items from the beginning of the buffer - I(dom, _unread >= head_sz); + I(sched, _unread >= head_sz); size_t tail_sz = _unread - head_sz; - I(dom, head_sz + tail_sz <= _buffer_sz); + I(sched, head_sz + tail_sz <= _buffer_sz); memcpy(ptr + head_sz, _buffer, tail_sz); } @@ -70,37 +70,37 @@ circular_buffer::transfer(void *dst) { */ void circular_buffer::enqueue(void *src) { - I(dom, src); - I(dom, _unread <= _buffer_sz); - I(dom, _buffer); + I(sched, src); + I(sched, _unread <= _buffer_sz); + I(sched, _buffer); // Grow if necessary. if (_unread == _buffer_sz) { grow(); } - DLOG(dom, mem, "circular_buffer enqueue " + DLOG(sched, mem, "circular_buffer enqueue " "unread: %d, next: %d, buffer_sz: %d, unit_sz: %d", _unread, _next, _buffer_sz, unit_sz); - I(dom, _unread < _buffer_sz); - I(dom, _unread + unit_sz <= _buffer_sz); + I(sched, _unread < _buffer_sz); + I(sched, _unread + unit_sz <= _buffer_sz); // Copy data size_t dst_idx = _next + _unread; - I(dom, dst_idx >= _buffer_sz || dst_idx + unit_sz <= _buffer_sz); + I(sched, dst_idx >= _buffer_sz || dst_idx + unit_sz <= _buffer_sz); if (dst_idx >= _buffer_sz) { dst_idx -= _buffer_sz; - I(dom, _next >= unit_sz); - I(dom, dst_idx <= _next - unit_sz); + I(sched, _next >= unit_sz); + I(sched, dst_idx <= _next - unit_sz); } - I(dom, dst_idx + unit_sz <= _buffer_sz); + I(sched, dst_idx + unit_sz <= _buffer_sz); memcpy(&_buffer[dst_idx], src, unit_sz); _unread += unit_sz; - DLOG(dom, mem, "circular_buffer pushed data at index: %d", dst_idx); + DLOG(sched, mem, "circular_buffer pushed data at index: %d", dst_idx); } /** @@ -110,21 +110,21 @@ circular_buffer::enqueue(void *src) { */ void circular_buffer::dequeue(void *dst) { - I(dom, unit_sz > 0); - I(dom, _unread >= unit_sz); - I(dom, _unread <= _buffer_sz); - I(dom, _buffer); + I(sched, unit_sz > 0); + I(sched, _unread >= unit_sz); + I(sched, _unread <= _buffer_sz); + I(sched, _buffer); - DLOG(dom, mem, + DLOG(sched, mem, "circular_buffer dequeue " "unread: %d, next: %d, buffer_sz: %d, unit_sz: %d", _unread, _next, _buffer_sz, unit_sz); - I(dom, _next + unit_sz <= _buffer_sz); + I(sched, _next + unit_sz <= _buffer_sz); if (dst != NULL) { memcpy(dst, &_buffer[_next], unit_sz); } - DLOG(dom, mem, "shifted data from index %d", _next); + DLOG(sched, mem, "shifted data from index %d", _next); _unread -= unit_sz; _next += unit_sz; if (_next == _buffer_sz) { @@ -140,8 +140,8 @@ circular_buffer::dequeue(void *dst) { void circular_buffer::grow() { size_t new_buffer_sz = _buffer_sz * 2; - I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE); - DLOG(dom, mem, "circular_buffer is growing to %d bytes", new_buffer_sz); + I(sched, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE); + DLOG(sched, mem, "circular_buffer is growing to %d bytes", new_buffer_sz); void *new_buffer = task->malloc(new_buffer_sz); transfer(new_buffer); task->free(_buffer); @@ -153,8 +153,8 @@ circular_buffer::grow() { void circular_buffer::shrink() { size_t new_buffer_sz = _buffer_sz / 2; - I(dom, initial_size() <= new_buffer_sz); - DLOG(dom, mem, "circular_buffer is shrinking to %d bytes", new_buffer_sz); + I(sched, initial_size() <= new_buffer_sz); + DLOG(sched, mem, "circular_buffer is shrinking to %d bytes", new_buffer_sz); void *new_buffer = task->malloc(new_buffer_sz); transfer(new_buffer); task->free(_buffer); diff --git a/src/rt/circular_buffer.h b/src/rt/circular_buffer.h index 1e686ea6f1461..eb1e49494ea69 100644 --- a/src/rt/circular_buffer.h +++ b/src/rt/circular_buffer.h @@ -10,7 +10,7 @@ circular_buffer : public task_owned { static const size_t INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 8; static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24; - rust_dom *dom; + rust_scheduler *sched; public: rust_task *task; diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index c2a56d993d8c7..02ab54fd2e191 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -39,13 +39,13 @@ command_line_args : public kernel_owned size_t vec_fill = sizeof(rust_str *) * argc; size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill); void *mem = kernel->malloc(vec_alloc); - args = new (mem) rust_vec(task->dom, vec_alloc, 0, NULL); + args = new (mem) rust_vec(task->sched, vec_alloc, 0, NULL); rust_str **strs = (rust_str**) &args->data[0]; for (int i = 0; i < argc; ++i) { size_t str_fill = strlen(argv[i]) + 1; size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill); mem = kernel->malloc(str_alloc); - strs[i] = new (mem) rust_str(task->dom, str_alloc, str_fill, + strs[i] = new (mem) rust_str(task->sched, str_alloc, str_fill, (uint8_t const *)argv[i]); } args->fill = vec_fill; @@ -98,21 +98,21 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { rust_srv *srv = new rust_srv(); rust_kernel *kernel = new rust_kernel(srv); kernel->start(); - rust_dom *dom = kernel->get_domain(); + rust_scheduler *sched = kernel->get_scheduler(); command_line_args *args - = new (kernel) command_line_args(dom->root_task, argc, argv); + = new (kernel) command_line_args(sched->root_task, argc, argv); - DLOG(dom, dom, "startup: %d args in 0x%" PRIxPTR, + DLOG(sched, dom, "startup: %d args in 0x%" PRIxPTR, args->argc, (uintptr_t)args->args); for (int i = 0; i < args->argc; i++) { - DLOG(dom, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); + DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); } - dom->root_task->start(main_fn, (uintptr_t)args->args); + sched->root_task->start(main_fn, (uintptr_t)args->args); int num_threads = get_num_threads(); - DLOG(dom, dom, "Using %d worker threads.", num_threads); + DLOG(sched, dom, "Using %d worker threads.", num_threads); int ret = kernel->start_task_threads(num_threads); delete args; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 76455d0ca9980..a7325bc066d1b 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -9,7 +9,7 @@ extern "C" CDECL rust_str* last_os_error(rust_task *task) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; LOG(task, task, "last_os_error()"); #if defined(__WIN32__) @@ -47,7 +47,7 @@ last_os_error(rust_task *task) { task->fail(1); return NULL; } - rust_str *st = new (mem) rust_str(dom, alloc, fill, (const uint8_t *)buf); + rust_str *st = new (mem) rust_str(sched, alloc, fill, (const uint8_t *)buf); #ifdef __WIN32__ LocalFree((HLOCAL)buf); @@ -57,7 +57,7 @@ last_os_error(rust_task *task) { extern "C" CDECL rust_str * rust_getcwd(rust_task *task) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; LOG(task, task, "rust_getcwd()"); char cbuf[BUF_BYTES]; @@ -80,7 +80,7 @@ rust_getcwd(rust_task *task) { } rust_str *st; - st = new (mem) rust_str(dom, alloc, fill, (const uint8_t *)cbuf); + st = new (mem) rust_str(sched, alloc, fill, (const uint8_t *)cbuf); return st; } @@ -124,7 +124,7 @@ unsupervise(rust_task *task) { extern "C" CDECL rust_vec* vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; LOG(task, mem, "vec_alloc %" PRIdPTR " elements of size %" PRIdPTR, n_elts, elem_t->size); size_t fill = n_elts * elem_t->size; @@ -134,7 +134,7 @@ vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts) task->fail(4); return NULL; } - rust_vec *vec = new (mem) rust_vec(dom, alloc, 0, NULL); + rust_vec *vec = new (mem) rust_vec(sched, alloc, 0, NULL); return vec; } @@ -198,11 +198,11 @@ vec_alloc_with_data(rust_task *task, size_t elt_size, void *d) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; size_t alloc = next_power_of_two(sizeof(rust_vec) + (n_elts * elt_size)); void *mem = task->malloc(alloc, memory_region::LOCAL); if (!mem) return NULL; - return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d); + return new (mem) rust_vec(sched, alloc, fill * elt_size, (uint8_t*)d); } extern "C" CDECL rust_vec* @@ -355,13 +355,13 @@ str_from_buf(rust_task *task, char *buf, unsigned int len) { extern "C" CDECL void * rand_new(rust_task *task) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; randctx *rctx = (randctx *) task->malloc(sizeof(randctx)); if (!rctx) { task->fail(1); return NULL; } - isaac_init(dom, rctx); + isaac_init(sched, rctx); return rctx; } diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp index bf75c89057ba2..778fb6b16fdf2 100644 --- a/src/rt/rust_chan.cpp +++ b/src/rt/rust_chan.cpp @@ -22,7 +22,7 @@ rust_chan::rust_chan(rust_task *task, rust_chan::~rust_chan() { LOG(task, comm, "del rust_chan(task=0x%" PRIxPTR ")", (uintptr_t) this); - A(task->dom, is_associated() == false, + A(task->sched, is_associated() == false, "Channel must be disassociated before being freed."); --task->ref_count; } @@ -49,7 +49,7 @@ bool rust_chan::is_associated() { * Unlink this channel from its associated port. */ void rust_chan::disassociate() { - A(task->dom, is_associated(), "Channel must be associated with a port."); + A(task->sched, is_associated(), "Channel must be associated with a port."); if (port->is_proxy() == false) { LOG(task, task, @@ -69,14 +69,14 @@ void rust_chan::disassociate() { void rust_chan::send(void *sptr) { buffer.enqueue(sptr); - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; if (!is_associated()) { - W(dom, is_associated(), + W(sched, is_associated(), "rust_chan::transmit with no associated port."); return; } - A(dom, !buffer.is_empty(), + A(sched, !buffer.is_empty(), "rust_chan::transmit with nothing to send."); if (port->is_proxy()) { @@ -86,7 +86,7 @@ void rust_chan::send(void *sptr) { } else { rust_port *target_port = port->referent(); if (target_port->task->blocked_on(target_port)) { - DLOG(dom, comm, "dequeued in rendezvous_ptr"); + DLOG(sched, comm, "dequeued in rendezvous_ptr"); buffer.dequeue(target_port->task->rendezvous_ptr); target_port->task->rendezvous_ptr = 0; target_port->task->wakeup(target_port); diff --git a/src/rt/rust_crate_cache.cpp b/src/rt/rust_crate_cache.cpp index 70509dcae95fe..7d3822d253a36 100644 --- a/src/rt/rust_crate_cache.cpp +++ b/src/rt/rust_crate_cache.cpp @@ -7,16 +7,16 @@ rust_crate_cache::get_type_desc(size_t size, size_t n_descs, type_desc const **descs) { - I(dom, n_descs > 1); + I(sched, n_descs > 1); type_desc *td = NULL; size_t keysz = n_descs * sizeof(type_desc*); HASH_FIND(hh, this->type_descs, descs, keysz, td); if (td) { - DLOG(dom, cache, "rust_crate_cache::get_type_desc hit"); + DLOG(sched, cache, "rust_crate_cache::get_type_desc hit"); return td; } - DLOG(dom, cache, "rust_crate_cache::get_type_desc miss"); - td = (type_desc*) dom->kernel->malloc(sizeof(type_desc) + keysz); + DLOG(sched, cache, "rust_crate_cache::get_type_desc miss"); + td = (type_desc*) sched->kernel->malloc(sizeof(type_desc) + keysz); if (!td) return NULL; // By convention, desc 0 is the root descriptor. @@ -27,7 +27,7 @@ rust_crate_cache::get_type_desc(size_t size, td->size = size; td->align = align; for (size_t i = 0; i < n_descs; ++i) { - DLOG(dom, cache, + DLOG(sched, cache, "rust_crate_cache::descs[%" PRIdPTR "] = 0x%" PRIxPTR, i, descs[i]); td->descs[i] = descs[i]; @@ -38,22 +38,22 @@ rust_crate_cache::get_type_desc(size_t size, return td; } -rust_crate_cache::rust_crate_cache(rust_dom *dom) +rust_crate_cache::rust_crate_cache(rust_scheduler *sched) : type_descs(NULL), - dom(dom), + sched(sched), idx(0) { } void rust_crate_cache::flush() { - DLOG(dom, cache, "rust_crate_cache::flush()"); + DLOG(sched, cache, "rust_crate_cache::flush()"); while (type_descs) { type_desc *d = type_descs; HASH_DEL(type_descs, d); - DLOG(dom, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d); - dom->kernel->free(d); + DLOG(sched, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d); + sched->kernel->free(d); } } diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index ac201fc799ccb..a57ef607f60ea 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -50,7 +50,7 @@ extern "C" { #include "sync/lock_and_signal.h" #include "sync/lock_free_queue.h" -struct rust_dom; +struct rust_scheduler; struct rust_task; class rust_log; class rust_port; @@ -174,7 +174,7 @@ template class ptr_vec : public task_owned > { #include "rust_proxy.h" #include "rust_kernel.h" #include "rust_message.h" -#include "rust_dom.h" +#include "rust_scheduler.h" struct rust_timer { // FIXME: This will probably eventually need replacement @@ -183,7 +183,7 @@ struct rust_timer { // For now it's just the most basic "thread that can interrupt // its associated domain-thread" device, so that we have // *some* form of task-preemption. - rust_dom *dom; + rust_scheduler *sched; uintptr_t exit_flag; #if defined(__WIN32__) @@ -193,7 +193,7 @@ struct rust_timer { pthread_t thread; #endif - rust_timer(rust_dom *dom); + rust_timer(rust_scheduler *sched); ~rust_timer(); }; diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index ee709fb191fe2..f3ebfd4f4b951 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -13,55 +13,55 @@ rust_kernel::rust_kernel(rust_srv *srv) : _srv(srv), _interrupt_kernel_loop(FALSE) { - dom = create_domain("main"); + sched = create_scheduler("main"); } -rust_dom * -rust_kernel::create_domain(const char *name) { +rust_scheduler * +rust_kernel::create_scheduler(const char *name) { _kernel_lock.lock(); rust_message_queue *message_queue = new (this) rust_message_queue(_srv, this); rust_srv *srv = _srv->clone(); - rust_dom *dom = - new (this) rust_dom(this, message_queue, srv, name); - rust_handle *handle = internal_get_dom_handle(dom); + rust_scheduler *sched = + new (this) rust_scheduler(this, message_queue, srv, name); + rust_handle *handle = internal_get_sched_handle(sched); message_queue->associate(handle); message_queues.append(message_queue); - KLOG("created domain: " PTR ", name: %s, index: %d", - dom, name, dom->list_index); + KLOG("created scheduler: " PTR ", name: %s, index: %d", + sched, name, sched->list_index); _kernel_lock.signal_all(); _kernel_lock.unlock(); - return dom; + return sched; } void -rust_kernel::destroy_domain() { +rust_kernel::destroy_scheduler() { _kernel_lock.lock(); - KLOG("deleting domain: " PTR ", name: %s, index: %d", - dom, dom->name, dom->list_index); - dom->message_queue->disassociate(); - rust_srv *srv = dom->srv; - delete dom; + KLOG("deleting scheduler: " PTR ", name: %s, index: %d", + sched, sched->name, sched->list_index); + sched->message_queue->disassociate(); + rust_srv *srv = sched->srv; + delete sched; delete srv; _kernel_lock.signal_all(); _kernel_lock.unlock(); } -rust_handle * -rust_kernel::internal_get_dom_handle(rust_dom *dom) { - rust_handle *handle = NULL; - if (_dom_handles.get(dom, &handle) == false) { +rust_handle * +rust_kernel::internal_get_sched_handle(rust_scheduler *sched) { + rust_handle *handle = NULL; + if (_sched_handles.get(sched, &handle) == false) { handle = - new (this) rust_handle(this, dom->message_queue, dom); - _dom_handles.put(dom, handle); + new (this) rust_handle(this, sched->message_queue, sched); + _sched_handles.put(sched, handle); } return handle; } -rust_handle * -rust_kernel::get_dom_handle(rust_dom *dom) { +rust_handle * +rust_kernel::get_sched_handle(rust_scheduler *sched) { _kernel_lock.lock(); - rust_handle *handle = internal_get_dom_handle(dom); + rust_handle *handle = internal_get_sched_handle(sched); _kernel_lock.unlock(); return handle; } @@ -72,7 +72,7 @@ rust_kernel::get_task_handle(rust_task *task) { rust_handle *handle = NULL; if (_task_handles.get(task, &handle) == false) { handle = - new (this) rust_handle(this, task->dom->message_queue, + new (this) rust_handle(this, task->sched->message_queue, task); _task_handles.put(task, handle); } @@ -87,7 +87,7 @@ rust_kernel::get_port_handle(rust_port *port) { if (_port_handles.get(port, &handle) == false) { handle = new (this) rust_handle(this, - port->task->dom->message_queue, + port->task->sched->message_queue, port); _port_handles.put(port, handle); } @@ -96,9 +96,8 @@ rust_kernel::get_port_handle(rust_port *port) { } void -rust_kernel::log_all_domain_state() { - KLOG("log_all_domain_state"); - dom->log_state(); +rust_kernel::log_all_scheduler_state() { + sched->log_state(); } /** @@ -159,7 +158,7 @@ rust_kernel::terminate_kernel_loop() { } rust_kernel::~rust_kernel() { - destroy_domain(); + destroy_scheduler(); terminate_kernel_loop(); @@ -175,8 +174,8 @@ rust_kernel::~rust_kernel() { KLOG("..task handles freed"); free_handles(_port_handles); KLOG("..port handles freed"); - free_handles(_dom_handles); - KLOG("..dom handles freed"); + free_handles(_sched_handles); + KLOG("..sched handles freed"); KLOG("freeing queues"); @@ -235,14 +234,14 @@ int rust_kernel::start_task_threads(int num_threads) threads.push(thread); } - dom->start_main_loop(0); + sched->start_main_loop(0); while(threads.pop(&thread)) { thread->join(); delete thread; } - return dom->rval; + return sched->rval; } #ifdef __WIN32__ @@ -257,9 +256,9 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) { NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL ); - DLOG_ERR(dom, dom, "%s failed with error %ld: %s", fn, err, buf); + DLOG_ERR(sched, dom, "%s failed with error %ld: %s", fn, err, buf); LocalFree((HLOCAL)buf); - I(dom, ok); + I(sched, ok); } } #endif @@ -271,7 +270,7 @@ rust_task_thread::rust_task_thread(int id, rust_kernel *owner) void rust_task_thread::run() { - owner->dom->start_main_loop(id); + owner->sched->start_main_loop(id); } // diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index b3befab28d2ac..a1fba33bf8918 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -52,7 +52,7 @@ class rust_kernel : public rust_thread { */ hash_map *> _task_handles; hash_map *> _port_handles; - hash_map *> _dom_handles; + hash_map *> _sched_handles; template void free_handles(hash_map* > &map); @@ -65,15 +65,16 @@ class rust_kernel : public rust_thread { void terminate_kernel_loop(); void pump_message_queues(); - rust_handle *internal_get_dom_handle(rust_dom *dom); + rust_handle * + internal_get_sched_handle(rust_scheduler *sched); - rust_dom *create_domain(const char *name); - void destroy_domain(); + rust_scheduler *create_scheduler(const char *name); + void destroy_scheduler(); array_list threads; public: - rust_dom *dom; + rust_scheduler *sched; lock_and_signal scheduler_lock; /** @@ -85,7 +86,7 @@ class rust_kernel : public rust_thread { */ indexed_list message_queues; - rust_handle *get_dom_handle(rust_dom *dom); + rust_handle *get_sched_handle(rust_scheduler *sched); rust_handle *get_task_handle(rust_task *task); rust_handle *get_port_handle(rust_port *port); @@ -103,7 +104,7 @@ class rust_kernel : public rust_thread { void notify_message_enqueued(rust_message_queue *queue, rust_message *message); - void log_all_domain_state(); + void log_all_scheduler_state(); void log(uint32_t level, char const *fmt, ...); virtual ~rust_kernel(); @@ -111,7 +112,7 @@ class rust_kernel : public rust_thread { void free(void *mem); // FIXME: this should go away - inline rust_dom *get_domain() const { return dom; } + inline rust_scheduler *get_scheduler() const { return sched; } int start_task_threads(int num_threads); diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index 01e92e1f23dda..a2ab77b1b5513 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -23,9 +23,9 @@ static const char * _foreground_colors[] = { "[37m", static lock_and_signal _log_lock; static uint32_t _last_thread_id; -rust_log::rust_log(rust_srv *srv, rust_dom *dom) : +rust_log::rust_log(rust_srv *srv, rust_scheduler *sched) : _srv(srv), - _dom(dom), + _sched(sched), _use_colors(getenv("RUST_COLOR_LOG")) { } @@ -104,12 +104,12 @@ rust_log::trace_ln(rust_task *task, uint32_t level, char *message) { uint32_t thread_id = hash((uint32_t) pthread_self()); #endif char prefix[BUF_BYTES] = ""; - if (_dom && _dom->name) { + if (_sched && _sched->name) { append_string(prefix, "%04" PRIxPTR ":%.10s:", - thread_id, _dom->name); + thread_id, _sched->name); } else { append_string(prefix, "%04" PRIxPTR ":0x%08" PRIxPTR ":", - thread_id, (uintptr_t) _dom); + thread_id, (uintptr_t) _sched); } if (task) { if (task->name) { diff --git a/src/rt/rust_log.h b/src/rt/rust_log.h index 334b4d9477573..ce0d8f593efce 100644 --- a/src/rt/rust_log.h +++ b/src/rt/rust_log.h @@ -1,3 +1,4 @@ +// -*- c++ -*- #ifndef RUST_LOG_H #define RUST_LOG_H @@ -5,30 +6,30 @@ const uint32_t log_err = 0; const uint32_t log_note = 1; #define LOG(task, field, ...) \ - DLOG_LVL(log_note, task, task->dom, field, __VA_ARGS__) + DLOG_LVL(log_note, task, task->sched, field, __VA_ARGS__) #define LOG_ERR(task, field, ...) \ - DLOG_LVL(log_err, task, task->dom, field, __VA_ARGS__) -#define DLOG(dom, field, ...) \ - DLOG_LVL(log_note, NULL, dom, field, __VA_ARGS__) -#define DLOG_ERR(dom, field, ...) \ - DLOG_LVL(log_err, NULL, dom, field, __VA_ARGS__) -#define LOGPTR(dom, msg, ptrval) \ - DLOG_LVL(log_note, NULL, dom, mem, "%s 0x%" PRIxPTR, msg, ptrval) -#define DLOG_LVL(lvl, task, dom, field, ...) \ + DLOG_LVL(log_err, task, task->sched, field, __VA_ARGS__) +#define DLOG(sched, field, ...) \ + DLOG_LVL(log_note, NULL, sched, field, __VA_ARGS__) +#define DLOG_ERR(sched, field, ...) \ + DLOG_LVL(log_err, NULL, sched, field, __VA_ARGS__) +#define LOGPTR(sched, msg, ptrval) \ + DLOG_LVL(log_note, NULL, sched, mem, "%s 0x%" PRIxPTR, msg, ptrval) +#define DLOG_LVL(lvl, task, sched, field, ...) \ do { \ - rust_dom* _d_ = dom; \ + rust_scheduler* _d_ = sched; \ if (log_rt_##field >= lvl && _d_->log_lvl >= lvl) { \ _d_->log(task, lvl, __VA_ARGS__); \ } \ } while (0) -struct rust_dom; +struct rust_scheduler; struct rust_task; class rust_log { public: - rust_log(rust_srv *srv, rust_dom *dom); + rust_log(rust_srv *srv, rust_scheduler *sched); virtual ~rust_log(); enum ansi_color { @@ -53,7 +54,7 @@ class rust_log { private: rust_srv *_srv; - rust_dom *_dom; + rust_scheduler *_sched; bool _use_labels; bool _use_colors; void trace_ln(rust_task *task, char *message); diff --git a/src/rt/rust_message.cpp b/src/rt/rust_message.cpp index 6d1b7c528d282..716299e64fe19 100644 --- a/src/rt/rust_message.cpp +++ b/src/rt/rust_message.cpp @@ -112,7 +112,7 @@ void data_message::kernel_process() { rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) : region(srv, true), kernel(kernel), - dom_handle(NULL) { + sched_handle(NULL) { // Nop. } diff --git a/src/rt/rust_message.h b/src/rt/rust_message.h index e9ce94bfa9e1f..6b95c9ffec784 100644 --- a/src/rt/rust_message.h +++ b/src/rt/rust_message.h @@ -93,26 +93,26 @@ class rust_message_queue : public lock_free_queue, public: memory_region region; rust_kernel *kernel; - rust_handle *dom_handle; + rust_handle *sched_handle; int32_t list_index; rust_message_queue(rust_srv *srv, rust_kernel *kernel); - void associate(rust_handle *dom_handle) { - this->dom_handle = dom_handle; + void associate(rust_handle *sched_handle) { + this->sched_handle = sched_handle; } /** * The Rust domain relinquishes control to the Rust kernel. */ void disassociate() { - this->dom_handle = NULL; + this->sched_handle = NULL; } /** * Checks if a Rust domain is responsible for draining the message queue. */ bool is_associated() { - return this->dom_handle != NULL; + return this->sched_handle != NULL; } void enqueue(rust_message* message) { diff --git a/src/rt/rust_dom.cpp b/src/rt/rust_scheduler.cpp similarity index 92% rename from src/rt/rust_dom.cpp rename to src/rt/rust_scheduler.cpp index ac3c3a82a4065..4ada1ae56973d 100644 --- a/src/rt/rust_dom.cpp +++ b/src/rt/rust_scheduler.cpp @@ -3,7 +3,7 @@ #include "rust_internal.h" #include "globals.h" -rust_dom::rust_dom(rust_kernel *kernel, +rust_scheduler::rust_scheduler(rust_kernel *kernel, rust_message_queue *message_queue, rust_srv *srv, const char *name) : interrupt_flag(0), @@ -32,8 +32,8 @@ rust_dom::rust_dom(rust_kernel *kernel, root_task = create_task(NULL, name); } -rust_dom::~rust_dom() { - DLOG(this, dom, "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this); +rust_scheduler::~rust_scheduler() { + DLOG(this, dom, "~rust_scheduler %s @0x%" PRIxPTR, name, (uintptr_t)this); newborn_tasks.delete_all(); running_tasks.delete_all(); @@ -45,7 +45,7 @@ rust_dom::~rust_dom() { } void -rust_dom::activate(rust_task *task) { +rust_scheduler::activate(rust_task *task) { context ctx; task->ctx.next = &ctx; @@ -57,7 +57,7 @@ rust_dom::activate(rust_task *task) { } void -rust_dom::log(rust_task* task, uint32_t level, char const *fmt, ...) { +rust_scheduler::log(rust_task* task, uint32_t level, char const *fmt, ...) { char buf[BUF_BYTES]; va_list args; va_start(args, fmt); @@ -67,7 +67,7 @@ rust_dom::log(rust_task* task, uint32_t level, char const *fmt, ...) { } void -rust_dom::fail() { +rust_scheduler::fail() { log(NULL, log_err, "domain %s @0x%" PRIxPTR " root task failed", name, this); I(this, rval == 0); @@ -75,7 +75,7 @@ rust_dom::fail() { } size_t -rust_dom::number_of_live_tasks() { +rust_scheduler::number_of_live_tasks() { return running_tasks.length() + blocked_tasks.length(); } @@ -83,7 +83,7 @@ rust_dom::number_of_live_tasks() { * Delete any dead tasks. */ void -rust_dom::reap_dead_tasks() { +rust_scheduler::reap_dead_tasks() { I(this, kernel->scheduler_lock.lock_held_by_current_thread()); for (size_t i = 0; i < dead_tasks.length(); ) { rust_task *task = dead_tasks[i]; @@ -104,7 +104,7 @@ rust_dom::reap_dead_tasks() { /** * Drains and processes incoming pending messages. */ -void rust_dom::drain_incoming_message_queue(bool process) { +void rust_scheduler::drain_incoming_message_queue(bool process) { rust_message *message; while (message_queue->dequeue(&message)) { DLOG(this, comm, "<== receiving \"%s\" " PTR, @@ -124,7 +124,7 @@ void rust_dom::drain_incoming_message_queue(bool process) { * Returns NULL if no tasks can be scheduled. */ rust_task * -rust_dom::schedule_task() { +rust_scheduler::schedule_task() { I(this, this); // FIXME: in the face of failing tasks, this is not always right. // I(this, n_live_tasks() > 0); @@ -142,7 +142,7 @@ rust_dom::schedule_task() { } void -rust_dom::log_state() { +rust_scheduler::log_state() { if (log_rt_task < log_note) return; if (!running_tasks.is_empty()) { @@ -182,7 +182,7 @@ rust_dom::log_state() { * drop to zero. */ int -rust_dom::start_main_loop(int id) { +rust_scheduler::start_main_loop(int id) { kernel->scheduler_lock.lock(); // Make sure someone is watching, to pull us out of infinite loops. @@ -282,12 +282,12 @@ rust_dom::start_main_loop(int id) { } rust_crate_cache * -rust_dom::get_cache() { +rust_scheduler::get_cache() { return &cache; } rust_task * -rust_dom::create_task(rust_task *spawner, const char *name) { +rust_scheduler::create_task(rust_task *spawner, const char *name) { rust_task *task = new (this->kernel) rust_task (this, &newborn_tasks, spawner, name); DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s", diff --git a/src/rt/rust_dom.h b/src/rt/rust_scheduler.h similarity index 85% rename from src/rt/rust_dom.h rename to src/rt/rust_scheduler.h index 04a42b5fb01f9..d3e2df224c782 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_scheduler.h @@ -1,7 +1,7 @@ -#ifndef RUST_DOM_H -#define RUST_DOM_H +#ifndef RUST_SCHEDULER_H +#define RUST_SCHEDULER_H -struct rust_dom; +struct rust_scheduler; class rust_crate_cache @@ -18,15 +18,15 @@ rust_crate_cache public: - rust_dom *dom; + rust_scheduler *sched; size_t idx; - rust_crate_cache(rust_dom *dom); + rust_crate_cache(rust_scheduler *sched); ~rust_crate_cache(); void flush(); }; -struct rust_dom : public kernel_owned, rc_base +struct rust_scheduler : public kernel_owned, rc_base { // Fields known to the compiler: uintptr_t interrupt_flag; @@ -64,10 +64,10 @@ struct rust_dom : public kernel_owned, rc_base // Only a pointer to 'name' is kept, so it must live as long as this // domain. - rust_dom(rust_kernel *kernel, + rust_scheduler(rust_kernel *kernel, rust_message_queue *message_queue, rust_srv *srv, const char *name); - ~rust_dom(); + ~rust_scheduler(); void activate(rust_task *task); void log(rust_task *task, uint32_t level, char const *fmt, ...); rust_log & get_log(); @@ -89,7 +89,7 @@ struct rust_dom : public kernel_owned, rc_base }; inline rust_log & -rust_dom::get_log() { +rust_scheduler::get_log() { return _log; } @@ -104,4 +104,4 @@ rust_dom::get_log() { // End: // -#endif /* RUST_DOM_H */ +#endif /* RUST_SCHEDULER_H */ diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 385e084cd6cc5..2a3342c683d04 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -26,10 +26,10 @@ new_stk(rust_task *task, size_t minsz) minsz = min_stk_bytes; size_t sz = sizeof(stk_seg) + minsz; stk_seg *stk = (stk_seg *)task->malloc(sz); - LOGPTR(task->dom, "new stk", (uintptr_t)stk); + LOGPTR(task->sched, "new stk", (uintptr_t)stk); memset(stk, 0, sizeof(stk_seg)); stk->limit = (uintptr_t) &stk->data[minsz]; - LOGPTR(task->dom, "stk limit", stk->limit); + LOGPTR(task->sched, "stk limit", stk->limit); stk->valgrind_id = VALGRIND_STACK_REGISTER(&stk->data[0], &stk->data[minsz]); @@ -40,7 +40,7 @@ static void del_stk(rust_task *task, stk_seg *stk) { VALGRIND_STACK_DEREGISTER(stk->valgrind_id); - LOGPTR(task->dom, "freeing stk segment", (uintptr_t)stk); + LOGPTR(task->sched, "freeing stk segment", (uintptr_t)stk); task->free(stk); } @@ -52,16 +52,16 @@ del_stk(rust_task *task, stk_seg *stk) size_t const n_callee_saves = 4; size_t const callee_save_fp = 0; -rust_task::rust_task(rust_dom *dom, rust_task_list *state, +rust_task::rust_task(rust_scheduler *sched, rust_task_list *state, rust_task *spawner, const char *name) : maybe_proxy(this), stk(NULL), runtime_sp(0), rust_sp(0), gc_alloc_chain(0), - dom(dom), + sched(sched), cache(NULL), - kernel(dom->kernel), + kernel(sched->kernel), name(name), state(state), cond(NULL), @@ -71,11 +71,11 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, rendezvous_ptr(0), handle(NULL), active(false), - local_region(&dom->srv->local_region), - synchronized_region(&dom->srv->synchronized_region) + local_region(&sched->srv->local_region), + synchronized_region(&sched->srv->synchronized_region) { - LOGPTR(dom, "new task", (uintptr_t)this); - DLOG(dom, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this); + LOGPTR(sched, "new task", (uintptr_t)this); + DLOG(sched, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *this); stk = new_stk(this, 0); rust_sp = stk->limit; @@ -87,33 +87,13 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state, rust_task::~rust_task() { - DLOG(dom, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d", + DLOG(sched, task, "~rust_task %s @0x%" PRIxPTR ", refcnt=%d", name, (uintptr_t)this, ref_count); - /* - for (uintptr_t fp = get_fp(); fp; fp = get_previous_fp(fp)) { - frame_glue_fns *glue_fns = get_frame_glue_fns(fp); - DLOG(dom, task, - "~rust_task, frame fp=0x%" PRIxPTR ", glue_fns=0x%" PRIxPTR, - fp, glue_fns); - if (glue_fns) { - DLOG(dom, task, - "~rust_task, mark_glue=0x%" PRIxPTR, - glue_fns->mark_glue); - DLOG(dom, task, - "~rust_task, drop_glue=0x%" PRIxPTR, - glue_fns->drop_glue); - DLOG(dom, task, - "~rust_task, reloc_glue=0x%" PRIxPTR, - glue_fns->reloc_glue); - } - } - */ - /* FIXME: tighten this up, there are some more assertions that hold at task-lifecycle events. */ - I(dom, ref_count == 0 || - (ref_count == 1 && this == dom->root_task)); + I(sched, ref_count == 0 || + (ref_count == 1 && this == sched->root_task)); del_stk(this, stk); } @@ -147,7 +127,7 @@ void task_start_wrapper(spawn_args *a) // This is duplicated from upcall_exit, which is probably dead code by // now. LOG(task, task, "task ref_count: %d", task->ref_count); - A(task->dom, task->ref_count >= 0, + A(task->sched, task->ref_count >= 0, "Task ref_count should not be negative on exit!"); task->die(); task->notify_tasks_waiting_to_join(); @@ -160,10 +140,10 @@ void rust_task::start(uintptr_t spawnee_fn, uintptr_t args) { - LOGPTR(dom, "from spawnee", spawnee_fn); + LOGPTR(sched, "from spawnee", spawnee_fn); - I(dom, stk->data != NULL); - I(dom, !kernel->scheduler_lock.lock_held_by_current_thread()); + I(sched, stk->data != NULL); + I(sched, !kernel->scheduler_lock.lock_held_by_current_thread()); scoped_lock with(kernel->scheduler_lock); @@ -182,7 +162,7 @@ rust_task::start(uintptr_t spawnee_fn, ctx.call((void *)task_start_wrapper, a, sp); yield_timer.reset(0); - transition(&dom->newborn_tasks, &dom->running_tasks); + transition(&sched->newborn_tasks, &sched->running_tasks); } void @@ -227,8 +207,8 @@ rust_task::kill() { // Unblock the task so it can unwind. unblock(); - if (this == dom->root_task) - dom->fail(); + if (this == sched->root_task) + sched->fail(); LOG(this, task, "preparing to unwind task: 0x%" PRIxPTR, this); // run_on_resume(rust_unwind_glue); @@ -237,15 +217,15 @@ rust_task::kill() { void rust_task::fail(size_t nargs) { // See note in ::kill() regarding who should call this. - DLOG(dom, task, "task %s @0x%" PRIxPTR " failing", name, this); + DLOG(sched, task, "task %s @0x%" PRIxPTR " failing", name, this); backtrace(); // Unblock the task so it can unwind. unblock(); - if (this == dom->root_task) - dom->fail(); + if (this == sched->root_task) + sched->fail(); // run_after_return(nargs, rust_unwind_glue); if (supervisor) { - DLOG(dom, task, + DLOG(sched, task, "task %s @0x%" PRIxPTR " propagating failure to supervisor %s @0x%" PRIxPTR, name, this, supervisor->name, supervisor); @@ -259,14 +239,14 @@ void rust_task::gc(size_t nargs) { // FIXME: not presently implemented; was broken by rustc. - DLOG(dom, task, + DLOG(sched, task, "task %s @0x%" PRIxPTR " garbage collecting", name, this); } void rust_task::unsupervise() { - DLOG(dom, task, + DLOG(sched, task, "task %s @0x%" PRIxPTR " disconnecting from supervisor %s @0x%" PRIxPTR, name, this, supervisor->name, supervisor); @@ -302,13 +282,13 @@ rust_task::get_frame_glue_fns(uintptr_t fp) { bool rust_task::running() { - return state == &dom->running_tasks; + return state == &sched->running_tasks; } bool rust_task::blocked() { - return state == &dom->blocked_tasks; + return state == &sched->blocked_tasks; } bool @@ -320,13 +300,13 @@ rust_task::blocked_on(rust_cond *on) bool rust_task::dead() { - return state == &dom->dead_tasks; + return state == &sched->dead_tasks; } void rust_task::link_gc(gc_alloc *gcm) { - I(dom, gcm->prev == NULL); - I(dom, gcm->next == NULL); + I(sched, gcm->prev == NULL); + I(sched, gcm->next == NULL); gcm->prev = NULL; gcm->next = gc_alloc_chain; gc_alloc_chain = gcm; @@ -361,7 +341,7 @@ rust_task::malloc(size_t sz, type_desc *td) return mem; if (td) { gc_alloc *gcm = (gc_alloc*) mem; - DLOG(dom, task, "task %s @0x%" PRIxPTR + DLOG(sched, task, "task %s @0x%" PRIxPTR " allocated %d GC bytes = 0x%" PRIxPTR, name, (uintptr_t)this, sz, gcm); memset((void*) gcm, 0, sizeof(gc_alloc)); @@ -384,7 +364,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc) unlink_gc(gcm); sz += sizeof(gc_alloc); gcm = (gc_alloc*) realloc((void*)gcm, sz, memory_region::LOCAL); - DLOG(dom, task, "task %s @0x%" PRIxPTR + DLOG(sched, task, "task %s @0x%" PRIxPTR " reallocated %d GC bytes = 0x%" PRIxPTR, name, (uintptr_t)this, sz, gcm); if (!gcm) @@ -406,7 +386,7 @@ rust_task::free(void *p, bool is_gc) if (is_gc) { gc_alloc *gcm = (gc_alloc*)(((char *)p) - sizeof(gc_alloc)); unlink_gc(gcm); - DLOG(dom, mem, + DLOG(sched, mem, "task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR, name, (uintptr_t)this, gcm); free(gcm, memory_region::LOCAL); @@ -417,11 +397,11 @@ rust_task::free(void *p, bool is_gc) void rust_task::transition(rust_task_list *src, rust_task_list *dst) { - I(dom, kernel->scheduler_lock.lock_held_by_current_thread()); - DLOG(dom, task, + I(sched, kernel->scheduler_lock.lock_held_by_current_thread()); + DLOG(sched, task, "task %s " PTR " state change '%s' -> '%s' while in '%s'", name, (uintptr_t)this, src->name, dst->name, state->name); - I(dom, state == src); + I(sched, state == src); src->remove(this); dst->append(this); state = dst; @@ -431,30 +411,30 @@ void rust_task::block(rust_cond *on, const char* name) { LOG(this, task, "Blocking on 0x%" PRIxPTR ", cond: 0x%" PRIxPTR, (uintptr_t) on, (uintptr_t) cond); - A(dom, cond == NULL, "Cannot block an already blocked task."); - A(dom, on != NULL, "Cannot block on a NULL object."); + A(sched, cond == NULL, "Cannot block an already blocked task."); + A(sched, on != NULL, "Cannot block on a NULL object."); - transition(&dom->running_tasks, &dom->blocked_tasks); + transition(&sched->running_tasks, &sched->blocked_tasks); cond = on; cond_name = name; } void rust_task::wakeup(rust_cond *from) { - A(dom, cond != NULL, "Cannot wake up unblocked task."); + A(sched, cond != NULL, "Cannot wake up unblocked task."); LOG(this, task, "Blocked on 0x%" PRIxPTR " woken up on 0x%" PRIxPTR, (uintptr_t) cond, (uintptr_t) from); - A(dom, cond == from, "Cannot wake up blocked task on wrong condition."); + A(sched, cond == from, "Cannot wake up blocked task on wrong condition."); - transition(&dom->blocked_tasks, &dom->running_tasks); - I(dom, cond == from); + transition(&sched->blocked_tasks, &sched->running_tasks); + I(sched, cond == from); cond = NULL; cond_name = "none"; } void rust_task::die() { - transition(&dom->running_tasks, &dom->dead_tasks); + transition(&sched->running_tasks, &sched->dead_tasks); } void @@ -467,8 +447,8 @@ rust_crate_cache * rust_task::get_crate_cache() { if (!cache) { - DLOG(dom, task, "fetching cache for current crate"); - cache = dom->get_cache(); + DLOG(sched, task, "fetching cache for current crate"); + cache = sched->get_cache(); } return cache; } @@ -486,7 +466,7 @@ rust_task::backtrace() { rust_handle * rust_task::get_handle() { if (handle == NULL) { - handle = dom->kernel->get_task_handle(this); + handle = sched->kernel->get_task_handle(this); } return handle; } @@ -503,7 +483,7 @@ rust_task::malloc(size_t size, memory_region::memory_region_type type) { } else if (type == memory_region::SYNCHRONIZED) { return synchronized_region.malloc(size); } - I(dom, false); + I(sched, false); return NULL; } @@ -535,7 +515,7 @@ rust_task::realloc(void *mem, size_t size, void rust_task::free(void *mem, memory_region::memory_region_type type) { - DLOG(dom, mem, "rust_task::free(0x%" PRIxPTR ")", mem); + DLOG(sched, mem, "rust_task::free(0x%" PRIxPTR ")", mem); if (type == memory_region::LOCAL) { local_region.free(mem); } else if (type == memory_region::SYNCHRONIZED) { diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 5e61306af2e01..54287df441439 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -43,7 +43,7 @@ rust_task : public maybe_proxy, uintptr_t runtime_sp; // Runtime sp while task running. uintptr_t rust_sp; // Saved sp when not running. gc_alloc *gc_alloc_chain; // Linked list of GC allocations. - rust_dom *dom; + rust_scheduler *sched; rust_crate_cache *cache; // Fields known only to the runtime. @@ -83,7 +83,7 @@ rust_task : public maybe_proxy, memory_region synchronized_region; // Only a pointer to 'name' is kept, so it must live as long as this task. - rust_task(rust_dom *dom, + rust_task(rust_scheduler *sched, rust_task_list *state, rust_task *spawner, const char *name); @@ -111,8 +111,8 @@ rust_task : public maybe_proxy, void die(); void unblock(); - void check_active() { I(dom, dom->curr_task == this); } - void check_suspended() { I(dom, dom->curr_task != this); } + void check_active() { I(sched, sched->curr_task == this); } + void check_suspended() { I(sched, sched->curr_task != this); } // Print a backtrace, if the "bt" logging option is on. void backtrace(); diff --git a/src/rt/rust_task_list.cpp b/src/rt/rust_task_list.cpp index bb1224afa20bf..81441de35f572 100644 --- a/src/rt/rust_task_list.cpp +++ b/src/rt/rust_task_list.cpp @@ -1,16 +1,16 @@ #include "rust_internal.h" -rust_task_list::rust_task_list (rust_dom *dom, const char* name) : - dom(dom), name(name) { +rust_task_list::rust_task_list (rust_scheduler *sched, const char* name) : + sched(sched), name(name) { // Nop; } void rust_task_list::delete_all() { - DLOG(dom, task, "deleting all %s tasks", name); + DLOG(sched, task, "deleting all %s tasks", name); while (is_empty() == false) { rust_task *task = pop_value(); - DLOG(dom, task, "deleting task " PTR, task); + DLOG(sched, task, "deleting task " PTR, task); delete task; } } diff --git a/src/rt/rust_task_list.h b/src/rt/rust_task_list.h index 479f9e936fbc8..0991b32eed85f 100644 --- a/src/rt/rust_task_list.h +++ b/src/rt/rust_task_list.h @@ -1,4 +1,4 @@ -// -*- c++-mode -*- +// -*- c++ -*- #ifndef RUST_TASK_LIST_H #define RUST_TASK_LIST_H @@ -8,9 +8,9 @@ class rust_task_list : public indexed_list, public kernel_owned { public: - rust_dom *dom; + rust_scheduler *sched; const char* name; - rust_task_list (rust_dom *dom, const char* name); + rust_task_list (rust_scheduler *sched, const char* name); void delete_all(); }; diff --git a/src/rt/rust_timer.cpp b/src/rt/rust_timer.cpp index 2d732a2359169..2b1c33aa6b9e4 100644 --- a/src/rt/rust_timer.cpp +++ b/src/rt/rust_timer.cpp @@ -29,8 +29,8 @@ static void * timer_loop(void *ptr) { // We were handed the rust_timer that owns us. rust_timer *timer = (rust_timer *)ptr; - rust_dom *dom = timer->dom; - DLOG(dom, timer, "in timer 0x%" PRIxPTR, (uintptr_t)timer); + rust_scheduler *sched = timer->sched; + DLOG(sched, timer, "in timer 0x%" PRIxPTR, (uintptr_t)timer); size_t ms = TIME_SLICE_IN_MS; while (!timer->exit_flag) { @@ -39,10 +39,10 @@ timer_loop(void *ptr) { #else usleep(ms * 1000); #endif - DLOG(dom, timer, "timer 0x%" PRIxPTR - " interrupting domain 0x%" PRIxPTR, (uintptr_t) timer, - (uintptr_t) dom); - dom->interrupt_flag = 1; + DLOG(sched, timer, "timer 0x%" PRIxPTR + " interrupting schedain 0x%" PRIxPTR, (uintptr_t) timer, + (uintptr_t) sched); + sched->interrupt_flag = 1; } #if defined(__WIN32__) ExitThread(0); @@ -52,12 +52,12 @@ timer_loop(void *ptr) { return 0; } -rust_timer::rust_timer(rust_dom *dom) : - dom(dom), exit_flag(0) { - DLOG(dom, timer, "creating timer for domain 0x%" PRIxPTR, dom); +rust_timer::rust_timer(rust_scheduler *sched) : + sched(sched), exit_flag(0) { + DLOG(sched, timer, "creating timer for domain 0x%" PRIxPTR, sched); #if defined(__WIN32__) thread = CreateThread(NULL, 0, timer_loop, this, 0, NULL); - dom->kernel->win32_require("CreateThread", thread != NULL); + sched->kernel->win32_require("CreateThread", thread != NULL); if (RUNNING_ON_VALGRIND) Sleep(10); #else @@ -70,7 +70,7 @@ rust_timer::rust_timer(rust_dom *dom) : rust_timer::~rust_timer() { exit_flag = 1; #if defined(__WIN32__) - dom->kernel->win32_require("WaitForSingleObject", + sched->kernel->win32_require("WaitForSingleObject", WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0); #else diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index ce349b18e9d31..18d9f4c1e8cac 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -23,7 +23,7 @@ str_buf(rust_task *task, rust_str *s); extern "C" void upcall_grow_task(rust_task *task, size_t n_frame_bytes) { - I(task->dom, false); + I(task->sched, false); LOG_UPCALL_ENTRY(task); task->grow(n_frame_bytes); } @@ -31,44 +31,44 @@ upcall_grow_task(rust_task *task, size_t n_frame_bytes) { extern "C" CDECL void upcall_log_int(rust_task *task, uint32_t level, int32_t i) { LOG_UPCALL_ENTRY(task); - if (task->dom->log_lvl >= level) - task->dom->log(task, level, "rust: %" PRId32 " (0x%" PRIx32 ")", + if (task->sched->log_lvl >= level) + task->sched->log(task, level, "rust: %" PRId32 " (0x%" PRIx32 ")", i, i); } extern "C" CDECL void upcall_log_float(rust_task *task, uint32_t level, float f) { LOG_UPCALL_ENTRY(task); - if (task->dom->log_lvl >= level) - task->dom->log(task, level, "rust: %12.12f", f); + if (task->sched->log_lvl >= level) + task->sched->log(task, level, "rust: %12.12f", f); } extern "C" CDECL void upcall_log_double(rust_task *task, uint32_t level, double *f) { LOG_UPCALL_ENTRY(task); - if (task->dom->log_lvl >= level) - task->dom->log(task, level, "rust: %12.12f", *f); + if (task->sched->log_lvl >= level) + task->sched->log(task, level, "rust: %12.12f", *f); } extern "C" CDECL void upcall_log_str(rust_task *task, uint32_t level, rust_str *str) { LOG_UPCALL_ENTRY(task); - if (task->dom->log_lvl >= level) { + if (task->sched->log_lvl >= level) { const char *c = str_buf(task, str); - task->dom->log(task, level, "rust: %s", c); + task->sched->log(task, level, "rust: %s", c); } } extern "C" CDECL void upcall_trace_word(rust_task *task, uintptr_t i) { LOG_UPCALL_ENTRY(task); - task->dom->log(task, 2, "trace: 0x%" PRIxPTR "", i, i, (char) i); + task->sched->log(task, 2, "trace: 0x%" PRIxPTR "", i, i, (char) i); } extern "C" CDECL void upcall_trace_str(rust_task *task, char const *c) { LOG_UPCALL_ENTRY(task); - task->dom->log(task, 2, "trace: %s", c); + task->sched->log(task, 2, "trace: %s", c); } extern "C" CDECL rust_port* @@ -85,7 +85,7 @@ upcall_del_port(rust_task *task, rust_port *port) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); LOG(task, comm, "upcall del_port(0x%" PRIxPTR ")", (uintptr_t) port); - I(task->dom, !port->ref_count); + I(task->sched, !port->ref_count); delete port; } @@ -95,11 +95,11 @@ upcall_del_port(rust_task *task, rust_port *port) { extern "C" CDECL rust_chan* upcall_new_chan(rust_task *task, rust_port *port) { LOG_UPCALL_ENTRY(task); - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; LOG(task, comm, "upcall_new_chan(" "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")", (uintptr_t) task, task->name, port); - I(dom, port); + I(sched, port); return new (task) rust_chan(task, port, port->unit_sz); } @@ -127,7 +127,7 @@ void upcall_del_chan(rust_task *task, rust_chan *chan) { LOG(task, comm, "upcall del_chan(0x%" PRIxPTR ")", (uintptr_t) chan); - A(task->dom, chan->ref_count == 0, + A(task->sched, chan->ref_count == 0, "Channel's ref count should be zero."); if (chan->is_associated()) { @@ -174,7 +174,7 @@ upcall_clone_chan(rust_task *task, maybe_proxy *target, target_task = target->referent(); } else { rust_handle *handle = - task->dom->kernel->get_port_handle(port->as_referent()); + task->sched->kernel->get_port_handle(port->as_referent()); maybe_proxy *proxy = new rust_proxy (handle); LOG(task, mem, "new proxy: " PTR, proxy); port = proxy; @@ -275,7 +275,7 @@ upcall_exit(rust_task *task) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); LOG(task, task, "task ref_count: %d", task->ref_count); - A(task->dom, task->ref_count >= 0, + A(task->sched, task->ref_count >= 0, "Task ref_count should not be negative on exit!"); task->die(); task->notify_tasks_waiting_to_join(); @@ -308,8 +308,8 @@ extern "C" CDECL void upcall_free(rust_task *task, void* ptr, uintptr_t is_gc) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); - rust_dom *dom = task->dom; - DLOG(dom, mem, + rust_scheduler *sched = task->sched; + DLOG(sched, mem, "upcall free(0x%" PRIxPTR ", is_gc=%" PRIdPTR ")", (uintptr_t)ptr, is_gc); task->free(ptr, (bool) is_gc); @@ -320,11 +320,11 @@ upcall_mark(rust_task *task, void* ptr) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; if (ptr) { gc_alloc *gcm = (gc_alloc*) (((char*)ptr) - sizeof(gc_alloc)); uintptr_t marked = (uintptr_t) gcm->mark(); - DLOG(dom, gc, "upcall mark(0x%" PRIxPTR ") = %" PRIdPTR, + DLOG(sched, gc, "upcall mark(0x%" PRIxPTR ") = %" PRIdPTR, (uintptr_t)gcm, marked); return marked; } @@ -332,14 +332,14 @@ upcall_mark(rust_task *task, void* ptr) { } rust_str *make_str(rust_task *task, char const *s, size_t fill) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; size_t alloc = next_power_of_two(sizeof(rust_str) + fill); void *mem = task->malloc(alloc); if (!mem) { task->fail(3); return NULL; } - rust_str *st = new (mem) rust_str(dom, alloc, fill, (uint8_t const *) s); + rust_str *st = new (mem) rust_str(sched, alloc, fill, (uint8_t const *) s); LOG(task, mem, "upcall new_str('%s', %" PRIdPTR ") = 0x%" PRIxPTR, s, fill, st); @@ -366,15 +366,15 @@ extern "C" CDECL rust_vec * upcall_new_vec(rust_task *task, size_t fill, type_desc *td) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); - rust_dom *dom = task->dom; - DLOG(dom, mem, "upcall new_vec(%" PRIdPTR ")", fill); + rust_scheduler *sched = task->sched; + DLOG(sched, mem, "upcall new_vec(%" PRIdPTR ")", fill); size_t alloc = next_power_of_two(sizeof(rust_vec) + fill); void *mem = task->malloc(alloc, td); if (!mem) { task->fail(3); return NULL; } - rust_vec *v = new (mem) rust_vec(dom, alloc, 0, NULL); + rust_vec *v = new (mem) rust_vec(sched, alloc, 0, NULL); LOG(task, mem, "upcall new_vec(%" PRIdPTR ") = 0x%" PRIxPTR, fill, v); return v; @@ -387,7 +387,7 @@ vec_grow(rust_task *task, uintptr_t *need_copy, type_desc *td) { - rust_dom *dom = task->dom; + rust_scheduler *sched = task->sched; LOG(task, mem, "vec_grow(0x%" PRIxPTR ", %" PRIdPTR "), rc=%" PRIdPTR " alloc=%" PRIdPTR ", fill=%" PRIdPTR @@ -438,10 +438,10 @@ vec_grow(rust_task *task, if (v->ref_count != CONST_REFCOUNT) v->deref(); - v = new (mem) rust_vec(dom, alloc, 0, NULL); + v = new (mem) rust_vec(sched, alloc, 0, NULL); *need_copy = 1; } - I(dom, sizeof(rust_vec) + v->fill <= v->alloc); + I(sched, sizeof(rust_vec) + v->fill <= v->alloc); return v; } @@ -521,8 +521,8 @@ upcall_new_task(rust_task *spawner, rust_vec *name) { // name is a rust string structure. LOG_UPCALL_ENTRY(spawner); scoped_lock with(spawner->kernel->scheduler_lock); - rust_dom *dom = spawner->dom; - rust_task *task = dom->create_task(spawner, (const char *)name->data); + rust_scheduler *sched = spawner->sched; + rust_task *task = sched->create_task(spawner, (const char *)name->data); return task; } @@ -534,8 +534,8 @@ upcall_start_task(rust_task *spawner, size_t args_sz) { LOG_UPCALL_ENTRY(spawner); - rust_dom *dom = spawner->dom; - DLOG(dom, task, + rust_scheduler *sched = spawner->sched; + DLOG(sched, task, "upcall start_task(task %s @0x%" PRIxPTR ", spawnee 0x%" PRIxPTR ")", task->name, task, @@ -563,7 +563,7 @@ upcall_ivec_resize(rust_task *task, rust_ivec *v, size_t newsz) { scoped_lock with(task->kernel->scheduler_lock); - I(task->dom, !v->fill); + I(task->sched, !v->fill); size_t new_alloc = next_power_of_two(newsz); rust_ivec_heap *new_heap_part = (rust_ivec_heap *) diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index bd888c108f134..984cd978ec284 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -25,24 +25,24 @@ ptr_vec::ptr_vec(rust_task *task) : fill(0), data(new (task) T*[alloc]) { - I(task->dom, data); - DLOG(task->dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR, + I(task->sched, data); + DLOG(task->sched, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR, (uintptr_t)data, (uintptr_t)this); } template ptr_vec::~ptr_vec() { - I(task->dom, data); - DLOG(task->dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR, + I(task->sched, data); + DLOG(task->sched, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR, (uintptr_t)this, (uintptr_t)data); - I(task->dom, fill == 0); + I(task->sched, fill == 0); task->free(data); } template T *& ptr_vec::operator[](size_t offset) { - I(task->dom, data[offset]->idx == offset); + I(task->sched, data[offset]->idx == offset); return data[offset]; } @@ -50,14 +50,14 @@ template void ptr_vec::push(T *p) { - I(task->dom, data); - I(task->dom, fill <= alloc); + I(task->sched, data); + I(task->sched, fill <= alloc); if (fill == alloc) { alloc *= 2; data = (T **)task->realloc(data, alloc * sizeof(T*)); - I(task->dom, data); + I(task->sched, data); } - I(task->dom, fill < alloc); + I(task->sched, fill < alloc); p->idx = fill; data[fill++] = p; } @@ -80,13 +80,13 @@ template void ptr_vec::trim(size_t sz) { - I(task->dom, data); + I(task->sched, data); if (sz <= (alloc / 4) && (alloc / 2) >= INIT_SIZE) { alloc /= 2; - I(task->dom, alloc >= fill); + I(task->sched, alloc >= fill); data = (T **)task->realloc(data, alloc * sizeof(T*)); - I(task->dom, data); + I(task->sched, data); } } @@ -95,9 +95,9 @@ void ptr_vec::swap_delete(T *item) { /* Swap the endpoint into i and decr fill. */ - I(task->dom, data); - I(task->dom, fill > 0); - I(task->dom, item->idx < fill); + I(task->sched, data); + I(task->sched, fill > 0); + I(task->sched, item->idx < fill); fill--; if (fill > 0) { T *subst = data[fill]; @@ -127,22 +127,22 @@ next_power_of_two(size_t s) // Initialization helper for ISAAC RNG static inline void -isaac_init(rust_dom *dom, randctx *rctx) +isaac_init(rust_scheduler *sched, randctx *rctx) { memset(rctx, 0, sizeof(randctx)); #ifdef __WIN32__ { HCRYPTPROV hProv; - dom->kernel->win32_require + sched->kernel->win32_require (_T("CryptAcquireContext"), CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT|CRYPT_SILENT)); - dom->kernel->win32_require + sched->kernel->win32_require (_T("CryptGenRandom"), CryptGenRandom(hProv, sizeof(rctx->randrsl), (BYTE*)(&rctx->randrsl))); - dom->kernel->win32_require + sched->kernel->win32_require (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); } @@ -156,11 +156,11 @@ isaac_init(rust_dom *dom, randctx *rctx) } } else { int fd = open("/dev/urandom", O_RDONLY); - I(dom, fd > 0); - I(dom, + I(sched, fd > 0); + I(sched, read(fd, (void*) &rctx->randrsl, sizeof(rctx->randrsl)) == sizeof(rctx->randrsl)); - I(dom, close(fd) == 0); + I(sched, close(fd) == 0); } #endif randinit(rctx, 1); @@ -175,9 +175,10 @@ rust_vec : public rc_base size_t fill; size_t pad; // Pad to align data[0] to 16 bytes. uint8_t data[]; - rust_vec(rust_dom *dom, size_t alloc, size_t fill, uint8_t const *d) : - alloc(alloc), - fill(fill) + rust_vec(rust_scheduler *sched, size_t alloc, size_t fill, + uint8_t const *d) + : alloc(alloc), + fill(fill) { if (d) memcpy(&data[0], d, fill); From 830425b924b539c1cfb7a83a9f7f43ceb933f71f Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 12:54:41 -0700 Subject: [PATCH 8/9] Resurrecting the runtime unit tests, and modifying them so they compile under the latest refactoring changes. --- mk/rt.mk | 6 +++ src/rt/rust_internal.h | 4 ++ src/rt/rust_kernel.h | 4 +- src/rt/test/rust_test_harness.cpp | 40 ++++++++++++++++ src/rt/test/rust_test_harness.h | 22 +++++++++ src/rt/test/rust_test_runtime.cpp | 67 ++++++++++++++++++++++++++ src/rt/test/rust_test_runtime.h | 51 ++++++++++++++++++++ src/rt/test/rust_test_util.cpp | 78 +++++++++++++++++++++++++++++++ src/rt/test/rust_test_util.h | 41 ++++++++++++++++ 9 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 src/rt/test/rust_test_harness.cpp create mode 100644 src/rt/test/rust_test_harness.h create mode 100644 src/rt/test/rust_test_runtime.cpp create mode 100644 src/rt/test/rust_test_runtime.h create mode 100644 src/rt/test/rust_test_util.cpp create mode 100644 src/rt/test/rust_test_util.h diff --git a/mk/rt.mk b/mk/rt.mk index bd935d660ff8e..7ada4c0069520 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -25,6 +25,9 @@ RUNTIME_CS := rt/sync/timer.cpp \ rt/rust_srv.cpp \ rt/rust_kernel.cpp \ rt/memory_region.cpp \ + rt/test/rust_test_harness.cpp \ + rt/test/rust_test_runtime.cpp \ + rt/test/rust_test_util.cpp \ rt/arch/i386/context.cpp \ RUNTIME_LL := @@ -56,6 +59,9 @@ RUNTIME_HDR := rt/globals.h \ rt/rust_kernel.h \ rt/memory_region.h \ rt/memory.h \ + rt/test/rust_test_harness.h \ + rt/test/rust_test_runtime.h \ + rt/test/rust_test_util.h \ rt/arch/i386/context.h \ RUNTIME_DEF := rt/rustrt$(CFG_DEF_SUFFIX) diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index a57ef607f60ea..f10e55d40a09d 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -249,6 +249,10 @@ typedef ptr_vec rust_wait_queue; #include "rust_port.h" #include "memory.h" +#include "test/rust_test_harness.h" +#include "test/rust_test_util.h" +#include "test/rust_test_runtime.h" + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index a1fba33bf8918..bea5afd5de3cb 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -68,11 +68,11 @@ class rust_kernel : public rust_thread { rust_handle * internal_get_sched_handle(rust_scheduler *sched); + array_list threads; + rust_scheduler *create_scheduler(const char *name); void destroy_scheduler(); - array_list threads; - public: rust_scheduler *sched; lock_and_signal scheduler_lock; diff --git a/src/rt/test/rust_test_harness.cpp b/src/rt/test/rust_test_harness.cpp new file mode 100644 index 0000000000000..cca199dcdb98b --- /dev/null +++ b/src/rt/test/rust_test_harness.cpp @@ -0,0 +1,40 @@ +#include "../rust_internal.h" + +bool +rust_test::run() { + return false; +} + +const char * +rust_test::name() { + return "untitled"; +} + +rust_test_suite::rust_test_suite() { + tests.append(new rust_domain_test()); + tests.append(new rust_task_test(this)); + tests.append(new rust_array_list_test()); + tests.append(new rust_synchronized_indexed_list_test()); +} + +rust_test_suite::~rust_test_suite() { + +} + +bool +rust_test_suite::run() { + bool pass = true; + for (size_t i = 0; i < tests.size(); i++) { + rust_test *test = tests[i]; + printf("test: %s running ... \n", test->name()); + timer timer; + bool result = tests[i]->run(); + printf("test: %s %s %.2f ms\n", test->name(), + result ? "PASSED" : "FAILE", timer.get_elapsed_time_in_ms()); + if (result == false) { + pass = false; + } + } + return pass; +} + diff --git a/src/rt/test/rust_test_harness.h b/src/rt/test/rust_test_harness.h new file mode 100644 index 0000000000000..401015e450890 --- /dev/null +++ b/src/rt/test/rust_test_harness.h @@ -0,0 +1,22 @@ +#ifndef RUST_TEST_HARNESS_H +#define RUST_TEST_HARNESS_H + +#define CHECK(x) if ((x) == false) \ + { printf("condition: %s failed at file: %s, line: %d\n", #x, \ + __FILE__, __LINE__ ); return false; } + +class rust_test { +public: + virtual bool run(); + virtual const char *name(); +}; + +class rust_test_suite : public rust_test { +public: + array_list tests; + rust_test_suite(); + virtual ~rust_test_suite(); + bool run(); +}; + +#endif /* RUST_TEST_HARNESS_H */ diff --git a/src/rt/test/rust_test_runtime.cpp b/src/rt/test/rust_test_runtime.cpp new file mode 100644 index 0000000000000..acb3557b8c1ce --- /dev/null +++ b/src/rt/test/rust_test_runtime.cpp @@ -0,0 +1,67 @@ +#include "rust_test_runtime.h" + +rust_test_runtime::rust_test_runtime() { +} + +rust_test_runtime::~rust_test_runtime() { +} + +#define DOMAINS 32 +#define TASKS 32 + +void +rust_domain_test::worker::run() { + rust_scheduler *handle = kernel->get_scheduler(); + for (int i = 0; i < TASKS; i++) { + handle->create_task(NULL, "child"); + } + sync::random_sleep(1000); +} + +bool +rust_domain_test::run() { + rust_srv srv; + rust_kernel kernel(&srv); + + array_list workers; + for (int i = 0; i < DOMAINS; i++) { + worker *worker = new rust_domain_test::worker (&kernel); + workers.append(worker); + worker->start(); + } + + // We don't join the worker threads here in order to simulate ad-hoc + // termination of domains. If we join_all_domains before all domains + // are actually spawned, this could crash, thus the reason for the + // sleep below. + + sync::sleep(100); + return true; +} + +void task_entry() { + printf("task entry\n"); +} + +void +rust_task_test::worker::run() { + rust_scheduler *scheduler = kernel->get_scheduler(); + scheduler->root_task->start((uintptr_t)&task_entry, (uintptr_t)NULL); + scheduler->start_main_loop(0); +} + +bool +rust_task_test::run() { + rust_srv srv; + rust_kernel kernel(&srv); + + array_list workers; + for (int i = 0; i < DOMAINS; i++) { + worker *worker = new rust_task_test::worker (&kernel, this); + workers.append(worker); + worker->start(); + } + + sync::random_sleep(1000); + return true; +} diff --git a/src/rt/test/rust_test_runtime.h b/src/rt/test/rust_test_runtime.h new file mode 100644 index 0000000000000..8d4f38ecb79f5 --- /dev/null +++ b/src/rt/test/rust_test_runtime.h @@ -0,0 +1,51 @@ +#include "../rust_internal.h" + +#ifndef RUST_TEST_RUNTIME_H +#define RUST_TEST_RUNTIME_H + +class rust_test_runtime { +public: + rust_test_runtime(); + virtual ~rust_test_runtime(); +}; + + +class rust_domain_test : public rust_test { +public: + class worker : public rust_thread { + public: + rust_kernel *kernel; + worker(rust_kernel *kernel) : kernel(kernel) { + // Nop. + } + void run(); + }; + bool run(); + const char *name() { + return "rust_domain_test"; + } +}; + +class rust_task_test : public rust_test { +public: + rust_test_suite *suite; + rust_task_test(rust_test_suite *suite) : suite(suite) { + // Nop. + } + class worker : public rust_thread { + public: + rust_kernel *kernel; + rust_task_test *parent; + worker(rust_kernel *kernel, rust_task_test *parent) : + kernel(kernel), parent(parent) { + // Nop. + } + void run(); + }; + bool run(); + const char *name() { + return "rust_task_test"; + } +}; + +#endif /* RUST_TEST_RUNTIME_H */ diff --git a/src/rt/test/rust_test_util.cpp b/src/rt/test/rust_test_util.cpp new file mode 100644 index 0000000000000..2e9d764f69b66 --- /dev/null +++ b/src/rt/test/rust_test_util.cpp @@ -0,0 +1,78 @@ +#include "../rust_internal.h" + +#define COUNT 1000 +#define LARGE_COUNT 10000 +#define THREADS 10 + +bool +rust_array_list_test::run() { + array_list list; + + for (int i = 0; i < COUNT; i++) { + list.append(i); + } + + for (int i = 0; i < COUNT; i++) { + CHECK (list[i] == i); + } + + for (int i = 0; i < COUNT; i++) { + CHECK (list.index_of(i) == i); + } + + for (int i = 0; i < COUNT; i++) { + CHECK (list.replace(i, -i)); + CHECK (list.replace(-i, i)); + CHECK (list.index_of(i) == i); + } + + for (int i = COUNT - 1; i >= 0; i--) { + CHECK (list.pop(NULL)); + } + + return true; +} + +bool +rust_synchronized_indexed_list_test::run() { + array_list workers; + + for (int i = 0; i < THREADS; i++) { + worker *worker = + new rust_synchronized_indexed_list_test::worker(this); + workers.append(worker); + } + + for (uint32_t i = 0; i < workers.size(); i++) { + workers[i]->start(); + } + + while(workers.is_empty() == false) { + worker *worker; + workers.pop(&worker); + worker->join(); + delete worker; + } + + long long expected_items = LARGE_COUNT * THREADS; + + CHECK(list.length() == expected_items); + + long long sum = 0; + for (size_t i = 0; i < list.length(); i++) { + sum += list[i]->value; + } + + long long expected_sum = LARGE_COUNT; + expected_sum = expected_sum * (expected_sum - 1) / 2 * THREADS; + CHECK (sum == expected_sum); + return true; +} + +void +rust_synchronized_indexed_list_test::worker::run() { + for (int i = 0; i < LARGE_COUNT; i++) { + parent->list.append(new indexed_list_element(i)); + } + return; +} diff --git a/src/rt/test/rust_test_util.h b/src/rt/test/rust_test_util.h new file mode 100644 index 0000000000000..41c3579043a15 --- /dev/null +++ b/src/rt/test/rust_test_util.h @@ -0,0 +1,41 @@ +#ifndef RUST_TEST_UTIL_H +#define RUST_TEST_UTIL_H + +class rust_test_util : public rust_test { +public: + +}; + +class rust_array_list_test : public rust_test { +public: + bool run(); + const char *name() { + return "rust_array_list_test"; + } +}; + + +class rust_synchronized_indexed_list_test : public rust_test { +public: + rust_srv srv; + synchronized_indexed_list > list; + + rust_synchronized_indexed_list_test() { + // Nop. + } + + class worker : public rust_thread { + public: + rust_synchronized_indexed_list_test *parent; + worker(rust_synchronized_indexed_list_test *parent) : parent(parent) { + // Nop. + } + void run(); + }; + bool run(); + const char *name() { + return "rust_synchronized_indexed_list_test"; + } +}; + +#endif /* RUST_TEST_UTIL_H */ From 711dcb8d23738971427b8a297ef48e40e64debe9 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 14:21:31 -0700 Subject: [PATCH 9/9] Re-enabling some tests. --- src/comp/back/upcall.rs | 2 +- src/comp/middle/trans.rs | 2 +- src/rt/rust_upcall.cpp | 4 ++-- src/test/run-pass/child-outlives-parent.rs | 7 +------ src/test/run-pass/spawn-types.rs | 2 -- src/test/run-pass/task-life-0.rs | 4 +--- 6 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 1ed0d4bbf9c25..5fad90ce031db 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -100,7 +100,7 @@ fn declare_upcalls(type_names tn, ModuleRef llmod) -> @upcalls { mark=d("mark", [T_ptr(T_i8())], T_int()), new_str=d("new_str", [T_ptr(T_i8()), T_size_t()], T_ptr(T_str())), - dup_str=d("dup_str", [T_ptr(T_str())], + dup_str=d("dup_str", [T_taskptr(tn), T_ptr(T_str())], T_ptr(T_str())), new_vec=d("new_vec", [T_size_t(), T_ptr(T_tydesc(tn))], T_opaque_vec_ptr()), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index aed4d3b753e27..4cc7a19787b5d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -6512,7 +6512,7 @@ fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task) else if(ty::type_is_str(tcx, t)) { ret rslt(bcx, bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str, - [bcx.fcx.lltaskptr, v])); + [bcx.fcx.lltaskptr, target_task, v])); } else if(ty::type_is_chan(tcx, t)) { // If this is a channel, we need to clone it. diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 18d9f4c1e8cac..f6257470b297a 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -355,11 +355,11 @@ upcall_new_str(rust_task *task, char const *s, size_t fill) { } extern "C" CDECL rust_str * -upcall_dup_str(rust_task *task, rust_str *str) { +upcall_dup_str(rust_task *task, rust_task *target, rust_str *str) { LOG_UPCALL_ENTRY(task); scoped_lock with(task->kernel->scheduler_lock); - return make_str(task, (char const *)str->data, str->fill); + return make_str(target, (char const *)str->data, str->fill); } extern "C" CDECL rust_vec * diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs index 9cd3b67821b93..4bf03ea243a9e 100644 --- a/src/test/run-pass/child-outlives-parent.rs +++ b/src/test/run-pass/child-outlives-parent.rs @@ -1,10 +1,5 @@ - - - // xfail-stage0 -// xfail-stage1 -// xfail-stage2 // Reported as issue #126, child leaks the string. fn child2(str s) { } -fn main() { auto x = spawn child2("hi"); } \ No newline at end of file +fn main() { auto x = spawn child2("hi"); } diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs index 0051b2ba14dbd..4bbeb3c064f11 100644 --- a/src/test/run-pass/spawn-types.rs +++ b/src/test/run-pass/spawn-types.rs @@ -5,8 +5,6 @@ */ // xfail-stage0 -// xfail-stage1 -// xfail-stage2 use std; diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs index 726dfa261e0a2..74d966c780bc8 100644 --- a/src/test/run-pass/task-life-0.rs +++ b/src/test/run-pass/task-life-0.rs @@ -1,10 +1,8 @@ // xfail-stage0 -// xfail-stage1 -// xfail-stage2 fn main() -> () { spawn child("Hello"); } fn child(str s) { -} \ No newline at end of file +}