diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-06-27 19:15:03 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-06-28 16:12:33 -0700 |
| commit | 49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb (patch) | |
| tree | fb74a37b34ec7334f273e1bc59c18d2daf439583 | |
| parent | f6f945fed5c8d1061d80b444331910df29afa392 (diff) | |
| download | rust-49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb.tar.gz rust-49a8cb34d2b6e3f7af4a7cbe842fe48ffa0245eb.zip | |
Removed dom_owned, splitting things between task_owned and kernel_owned. Had to re-xfail a few tests brson recently un-xfailed.
| -rw-r--r-- | src/rt/circular_buffer.cpp | 17 | ||||
| -rw-r--r-- | src/rt/circular_buffer.h | 8 | ||||
| -rw-r--r-- | src/rt/memory.h | 45 | ||||
| -rw-r--r-- | src/rt/rust.cpp | 31 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 6 | ||||
| -rw-r--r-- | src/rt/rust_chan.cpp | 2 | ||||
| -rw-r--r-- | src/rt/rust_crate_cache.cpp | 4 | ||||
| -rw-r--r-- | src/rt/rust_dom.cpp | 68 | ||||
| -rw-r--r-- | src/rt/rust_dom.h | 11 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 41 | ||||
| -rw-r--r-- | src/rt/rust_kernel.h | 9 | ||||
| -rw-r--r-- | src/rt/rust_message.cpp | 7 | ||||
| -rw-r--r-- | src/rt/rust_port.cpp | 4 | ||||
| -rw-r--r-- | src/rt/rust_task.cpp | 86 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 39 | ||||
| -rw-r--r-- | src/rt/rust_task_list.h | 3 | ||||
| -rw-r--r-- | src/rt/rust_upcall.cpp | 7 | ||||
| -rw-r--r-- | src/rt/rust_util.h | 49 | ||||
| -rw-r--r-- | src/test/run-pass/child-outlives-parent.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/spawn-types.rs | 2 | ||||
| -rw-r--r-- | 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 ab98dfe34c4..0239e40f997 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 cdd0b03b091..1e686ea6f14 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> { +circular_buffer : public task_owned<circular_buffer> { 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 9196e28dd83..d5e5a6eb1a7 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 2a491b61150..293d8562e4b 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> +command_line_args : public kernel_owned<command_line_args> { - 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<command_line_args> #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<command_line_args> #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<command_line_args> // 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 2a724ee1791..76455d0ca99 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 cc03c227acd..bf75c89057b 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 1f66e0e0084..70509dcae95 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 65ccf158b64..d89cb181fb8 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 dfc0960a9ea..b936a0e580a 100644 --- a/src/rt/rust_dom.h +++ b/src/rt/rust_dom.h @@ -35,8 +35,6 @@ struct rust_dom : public kernel_owned<rust_dom>, rc_base<rust_dom> 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<rust_dom>, rc_base<rust_dom> 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 cc494a26148..ac201fc799c 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -115,15 +115,9 @@ template <typename T> struct rc_base { ~rc_base(); }; -template <typename T> struct dom_owned { - void operator delete(void *ptr) { - ((T *)ptr)->dom->free(ptr); - } -}; - template <typename T> 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 <typename T> class ptr_vec : public dom_owned<ptr_vec<T> > { +template <typename T> class ptr_vec : public task_owned<ptr_vec<T> > { 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 @@ public: #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_alarm> 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 ee5cf99ef5d..5e03d8072d6 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -116,15 +116,6 @@ public: 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 19a1d8a367e..6d1b7c528d2 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 57d0b216836..a2bd3b34c38 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<rust_port>(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 325bb560502..52987c68d64 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<rust_task>(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 62a725a98d5..5e61306af2e 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<rust_task>, - public dom_owned<rust_task> + public kernel_owned<rust_task> { // Fields known to the compiler. stk_seg *stk; @@ -46,8 +71,6 @@ rust_task : public maybe_proxy<rust_task>, // List of tasks waiting for this task to finish. array_list<maybe_proxy<rust_task> *> tasks_waiting_to_join; - rust_alarm alarm; - rust_handle<rust_task> *handle; context ctx; @@ -56,6 +79,9 @@ rust_task : public maybe_proxy<rust_task>, // 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_task>, 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 b1fba75029d..479f9e936fb 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<rust_task>, - public dom_owned<rust_task_list> { + public kernel_owned<rust_task_list> { public: rust_dom *dom; const char* name; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index ccb35958a80..ce349b18e9d 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<rust_task> *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 fe3c2459966..260f7eb9d5d 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 <typename T> @@ -17,30 +19,30 @@ rc_base<T>::~rc_base() // Utility type: pointer-vector. template <typename T> -ptr_vec<T>::ptr_vec(rust_dom *dom) : - dom(dom), +ptr_vec<T>::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 <typename T> ptr_vec<T>::~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 <typename T> T *& ptr_vec<T>::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 <typename T> void ptr_vec<T>::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 <typename T> void ptr_vec<T>::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<T>::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 988172ba6ad..9cd3b67821b 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 4bbeb3c064f..0051b2ba14d 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 324572344a4..726dfa261e0 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"); } |
