1
Fork 0

Removed dom_owned, splitting things between task_owned and kernel_owned. Had to re-xfail a few tests brson recently un-xfailed.

This commit is contained in:
Eric Holk 2011-06-27 19:15:03 -07:00 committed by Graydon Hoare
parent f6f945fed5
commit 49a8cb34d2
21 changed files with 217 additions and 226 deletions

View file

@ -4,13 +4,14 @@
#include "rust_internal.h" #include "rust_internal.h"
circular_buffer::circular_buffer(rust_dom *dom, size_t unit_sz) : circular_buffer::circular_buffer(rust_task *task, size_t unit_sz) :
dom(dom), dom(task->dom),
task(task),
unit_sz(unit_sz), unit_sz(unit_sz),
_buffer_sz(initial_size()), _buffer_sz(initial_size()),
_next(0), _next(0),
_unread(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."); A(dom, unit_sz, "Unit size must be larger than zero.");
@ -26,7 +27,7 @@ circular_buffer::~circular_buffer() {
I(dom, _buffer); I(dom, _buffer);
W(dom, _unread == 0, W(dom, _unread == 0,
"freeing circular_buffer with %d unread bytes", _unread); "freeing circular_buffer with %d unread bytes", _unread);
dom->free(_buffer); task->free(_buffer);
} }
size_t size_t
@ -141,9 +142,9 @@ circular_buffer::grow() {
size_t new_buffer_sz = _buffer_sz * 2; size_t new_buffer_sz = _buffer_sz * 2;
I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE); I(dom, new_buffer_sz <= MAX_CIRCULAR_BUFFER_SIZE);
DLOG(dom, mem, "circular_buffer is growing to %d bytes", new_buffer_sz); 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); transfer(new_buffer);
dom->free(_buffer); task->free(_buffer);
_buffer = (uint8_t *)new_buffer; _buffer = (uint8_t *)new_buffer;
_next = 0; _next = 0;
_buffer_sz = new_buffer_sz; _buffer_sz = new_buffer_sz;
@ -154,9 +155,9 @@ circular_buffer::shrink() {
size_t new_buffer_sz = _buffer_sz / 2; size_t new_buffer_sz = _buffer_sz / 2;
I(dom, initial_size() <= new_buffer_sz); I(dom, initial_size() <= new_buffer_sz);
DLOG(dom, mem, "circular_buffer is shrinking to %d bytes", 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); transfer(new_buffer);
dom->free(_buffer); task->free(_buffer);
_buffer = (uint8_t *)new_buffer; _buffer = (uint8_t *)new_buffer;
_next = 0; _next = 0;
_buffer_sz = new_buffer_sz; _buffer_sz = new_buffer_sz;

View file

@ -6,15 +6,17 @@
#define CIRCULAR_BUFFER_H #define CIRCULAR_BUFFER_H
class 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 INITIAL_CIRCULAR_BUFFER_SIZE_IN_UNITS = 8;
static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24; static const size_t MAX_CIRCULAR_BUFFER_SIZE = 1 << 24;
public:
rust_dom *dom; rust_dom *dom;
public:
rust_task *task;
// Size of the data unit in bytes. // Size of the data unit in bytes.
const size_t unit_sz; 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(); ~circular_buffer();
void transfer(void *dst); void transfer(void *dst);
void enqueue(void *src); void enqueue(void *src);

View file

@ -1,3 +1,4 @@
// -*- c++ -*-
#ifndef MEMORY_H #ifndef MEMORY_H
#define MEMORY_H #define MEMORY_H
@ -5,50 +6,54 @@ inline void *operator new(size_t size, void *mem) {
return mem; return mem;
} }
inline void *operator new(size_t size, rust_dom *dom) { inline void *operator new(size_t size, rust_kernel *kernel) {
return dom->malloc(size, memory_region::LOCAL); return kernel->malloc(size);
} }
inline void *operator new[](size_t size, rust_dom *dom) { inline void *operator new(size_t size, rust_task *task) {
return dom->malloc(size, memory_region::LOCAL); 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 dom.malloc(size, memory_region::LOCAL); 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 dom.malloc(size, memory_region::LOCAL); 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) { 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) { 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) { 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) { 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) { inline void operator delete(void *mem, rust_task *task) {
dom->free(mem, memory_region::LOCAL); task->free(mem, memory_region::LOCAL);
return; 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) { memory_region::memory_region_type type) {
dom->free(mem, type); task->free(mem, type);
return; return;
} }

View file

@ -1,19 +1,21 @@
#include "rust_internal.h" #include "rust_internal.h"
struct 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; int argc;
char **argv; char **argv;
// vec[str] passed to rust_task::start. // vec[str] passed to rust_task::start.
rust_vec *args; rust_vec *args;
command_line_args(rust_dom *dom, command_line_args(rust_task *task,
int sys_argc, int sys_argc,
char **sys_argv) char **sys_argv)
: dom(dom), : kernel(task->kernel),
task(task),
argc(sys_argc), argc(sys_argc),
argv(sys_argv), argv(sys_argv),
args(NULL) args(NULL)
@ -21,7 +23,7 @@ command_line_args : public dom_owned<command_line_args>
#if defined(__WIN32__) #if defined(__WIN32__)
LPCWSTR cmdline = GetCommandLineW(); LPCWSTR cmdline = GetCommandLineW();
LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc); 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); argv = (char **) dom->malloc(sizeof(char*) * argc);
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, int n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
@ -36,14 +38,14 @@ command_line_args : public dom_owned<command_line_args>
#endif #endif
size_t vec_fill = sizeof(rust_str *) * argc; size_t vec_fill = sizeof(rust_str *) * argc;
size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill); size_t vec_alloc = next_power_of_two(sizeof(rust_vec) + vec_fill);
void *mem = dom->malloc(vec_alloc); void *mem = kernel->malloc(vec_alloc);
args = new (mem) rust_vec(dom, vec_alloc, 0, NULL); args = new (mem) rust_vec(task->dom, vec_alloc, 0, NULL);
rust_str **strs = (rust_str**) &args->data[0]; rust_str **strs = (rust_str**) &args->data[0];
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
size_t str_fill = strlen(argv[i]) + 1; size_t str_fill = strlen(argv[i]) + 1;
size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill); size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill);
mem = dom->malloc(str_alloc); mem = kernel->malloc(str_alloc);
strs[i] = new (mem) rust_str(dom, str_alloc, str_fill, strs[i] = new (mem) rust_str(task->dom, str_alloc, str_fill,
(uint8_t const *)argv[i]); (uint8_t const *)argv[i]);
} }
args->fill = vec_fill; 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. // Drop the args we've had pinned here.
rust_str **strs = (rust_str**) &args->data[0]; rust_str **strs = (rust_str**) &args->data[0];
for (int i = 0; i < argc; ++i) for (int i = 0; i < argc; ++i)
dom->free(strs[i]); kernel->free(strs[i]);
dom->free(args); kernel->free(args);
} }
#ifdef __WIN32__ #ifdef __WIN32__
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
dom->free(argv[i]); task->free(argv[i]);
} }
dom->free(argv); task->free(argv);
#endif #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); rust_kernel *kernel = new rust_kernel(srv);
kernel->start(); kernel->start();
rust_dom *dom = kernel->get_domain(); 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, DLOG(dom, dom, "startup: %d args in 0x%" PRIxPTR,
args->argc, (uintptr_t)args->args); args->argc, (uintptr_t)args->args);

View file

@ -42,7 +42,7 @@ last_os_error(rust_task *task) {
#endif #endif
size_t fill = strlen(buf) + 1; size_t fill = strlen(buf) + 1;
size_t alloc = next_power_of_two(sizeof(rust_str) + fill); 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) { if (!mem) {
task->fail(1); task->fail(1);
return NULL; return NULL;
@ -73,7 +73,7 @@ rust_getcwd(rust_task *task) {
size_t fill = strlen(cbuf) + 1; size_t fill = strlen(cbuf) + 1;
size_t alloc = next_power_of_two(sizeof(rust_str) + fill); 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) { if (!mem) {
task->fail(1); task->fail(1);
return NULL; return NULL;
@ -200,7 +200,7 @@ vec_alloc_with_data(rust_task *task,
{ {
rust_dom *dom = task->dom; rust_dom *dom = task->dom;
size_t alloc = next_power_of_two(sizeof(rust_vec) + (n_elts * elt_size)); 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; if (!mem) return NULL;
return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d); return new (mem) rust_vec(dom, alloc, fill * elt_size, (uint8_t*)d);
} }

View file

@ -9,7 +9,7 @@ rust_chan::rust_chan(rust_task *task,
size_t unit_sz) : size_t unit_sz) :
task(task), task(task),
port(port), port(port),
buffer(task->dom, unit_sz) { buffer(task, unit_sz) {
++task->ref_count; ++task->ref_count;
if (port) { if (port) {
associate(port); associate(port);

View file

@ -16,7 +16,7 @@ rust_crate_cache::get_type_desc(size_t size,
return td; return td;
} }
DLOG(dom, cache, "rust_crate_cache::get_type_desc miss"); 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) if (!td)
return NULL; return NULL;
// By convention, desc 0 is the root descriptor. // By convention, desc 0 is the root descriptor.
@ -53,7 +53,7 @@ rust_crate_cache::flush() {
type_desc *d = type_descs; type_desc *d = type_descs;
HASH_DEL(type_descs, d); HASH_DEL(type_descs, d);
DLOG(dom, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d); DLOG(dom, mem, "rust_crate_cache::flush() tydesc %" PRIxPTR, d);
dom->free(d); dom->kernel->free(d);
} }
} }

View file

@ -10,8 +10,6 @@ rust_dom::rust_dom(rust_kernel *kernel,
_log(srv, this), _log(srv, this),
log_lvl(log_note), log_lvl(log_note),
srv(srv), srv(srv),
local_region(&srv->local_region),
synchronized_region(&srv->synchronized_region),
name(name), name(name),
newborn_tasks(this, "newborn"), newborn_tasks(this, "newborn"),
running_tasks(this, "running"), running_tasks(this, "running"),
@ -36,6 +34,7 @@ rust_dom::rust_dom(rust_kernel *kernel,
rust_dom::~rust_dom() { rust_dom::~rust_dom() {
DLOG(this, dom, "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this); DLOG(this, dom, "~rust_dom %s @0x%" PRIxPTR, name, (uintptr_t)this);
newborn_tasks.delete_all(); newborn_tasks.delete_all();
running_tasks.delete_all(); running_tasks.delete_all();
blocked_tasks.delete_all(); blocked_tasks.delete_all();
@ -75,69 +74,6 @@ rust_dom::fail() {
rval = 1; 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__ #ifdef __WIN32__
void void
rust_dom::win32_require(LPCTSTR fn, BOOL ok) { rust_dom::win32_require(LPCTSTR fn, BOOL ok) {
@ -372,7 +308,7 @@ rust_dom::get_cache() {
rust_task * rust_task *
rust_dom::create_task(rust_task *spawner, const char *name) { rust_dom::create_task(rust_task *spawner, const char *name) {
rust_task *task = 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", DLOG(this, task, "created task: " PTR ", spawner: %s, name: %s",
task, spawner ? spawner->name : "null", name); task, spawner ? spawner->name : "null", name);
newborn_tasks.append(task); newborn_tasks.append(task);

View file

@ -35,8 +35,6 @@ struct rust_dom : public kernel_owned<rust_dom>, rc_base<rust_dom>
rust_log _log; rust_log _log;
uint32_t log_lvl; uint32_t log_lvl;
rust_srv *srv; rust_srv *srv;
memory_region local_region;
memory_region synchronized_region;
const char *const name; const char *const name;
rust_task_list newborn_tasks; 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, ...); void log(rust_task *task, uint32_t level, char const *fmt, ...);
rust_log & get_log(); rust_log & get_log();
void fail(); 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); void drain_incoming_message_queue(bool process);

View file

@ -115,15 +115,9 @@ template <typename T> struct rc_base {
~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 { template <typename T> struct task_owned {
void operator delete(void *ptr) { 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. // 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; static const size_t INIT_SIZE = 8;
rust_dom *dom; rust_task *task;
size_t alloc; size_t alloc;
size_t fill; size_t fill;
T **data; T **data;
public: public:
ptr_vec(rust_dom *dom); ptr_vec(rust_task *task);
~ptr_vec(); ~ptr_vec();
size_t length() { size_t length() {
@ -181,7 +175,6 @@ public:
#include "rust_kernel.h" #include "rust_kernel.h"
#include "rust_message.h" #include "rust_message.h"
#include "rust_dom.h" #include "rust_dom.h"
#include "memory.h"
struct rust_timer { struct rust_timer {
// FIXME: This will probably eventually need replacement // FIXME: This will probably eventually need replacement
@ -250,35 +243,11 @@ rust_alarm
typedef ptr_vec<rust_alarm> rust_wait_queue; 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 "circular_buffer.h"
#include "rust_task.h" #include "rust_task.h"
#include "rust_chan.h" #include "rust_chan.h"
#include "rust_port.h" #include "rust_port.h"
#include "memory.h"
// //
// Local Variables: // Local Variables:

View file

@ -116,15 +116,6 @@ public:
int start_task_threads(int num_threads); 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 { class rust_task_thread : public rust_thread {
int id; int id;
rust_kernel *owner; rust_kernel *owner;

View file

@ -109,9 +109,10 @@ void data_message::kernel_process() {
} }
rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel) : rust_message_queue::rust_message_queue(rust_srv *srv, rust_kernel *kernel)
region (srv, true), kernel(kernel), : region(srv, true),
dom_handle(NULL) { kernel(kernel),
dom_handle(NULL) {
// Nop. // Nop.
} }

View file

@ -3,14 +3,14 @@
rust_port::rust_port(rust_task *task, size_t unit_sz) : rust_port::rust_port(rust_task *task, size_t unit_sz) :
maybe_proxy<rust_port>(this), task(task), 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, LOG(task, comm,
"new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%" "new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%"
PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this); PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this);
// Allocate a remote channel, for remote channel data. // 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() { rust_port::~rust_port() {

View file

@ -20,16 +20,16 @@ static size_t const min_stk_bytes = 0x100000;
// Task stack segments. Heap allocated and chained together. // Task stack segments. Heap allocated and chained together.
static stk_seg* static stk_seg*
new_stk(rust_dom *dom, size_t minsz) new_stk(rust_task *task, size_t minsz)
{ {
if (minsz < min_stk_bytes) if (minsz < min_stk_bytes)
minsz = min_stk_bytes; minsz = min_stk_bytes;
size_t sz = sizeof(stk_seg) + minsz; size_t sz = sizeof(stk_seg) + minsz;
stk_seg *stk = (stk_seg *)dom->malloc(sz); stk_seg *stk = (stk_seg *)task->malloc(sz);
LOGPTR(dom, "new stk", (uintptr_t)stk); LOGPTR(task->dom, "new stk", (uintptr_t)stk);
memset(stk, 0, sizeof(stk_seg)); memset(stk, 0, sizeof(stk_seg));
stk->limit = (uintptr_t) &stk->data[minsz]; stk->limit = (uintptr_t) &stk->data[minsz];
LOGPTR(dom, "stk limit", stk->limit); LOGPTR(task->dom, "stk limit", stk->limit);
stk->valgrind_id = stk->valgrind_id =
VALGRIND_STACK_REGISTER(&stk->data[0], VALGRIND_STACK_REGISTER(&stk->data[0],
&stk->data[minsz]); &stk->data[minsz]);
@ -37,11 +37,11 @@ new_stk(rust_dom *dom, size_t minsz)
} }
static void static void
del_stk(rust_dom *dom, stk_seg *stk) del_stk(rust_task *task, stk_seg *stk)
{ {
VALGRIND_STACK_DEREGISTER(stk->valgrind_id); VALGRIND_STACK_DEREGISTER(stk->valgrind_id);
LOGPTR(dom, "freeing stk segment", (uintptr_t)stk); LOGPTR(task->dom, "freeing stk segment", (uintptr_t)stk);
dom->free(stk); task->free(stk);
} }
// Tasks // 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::rust_task(rust_dom *dom, rust_task_list *state,
rust_task *spawner, const char *name) : rust_task *spawner, const char *name) :
maybe_proxy<rust_task>(this), maybe_proxy<rust_task>(this),
stk(new_stk(dom, 0)), stk(NULL),
runtime_sp(0), runtime_sp(0),
rust_sp(stk->limit), rust_sp(NULL),
gc_alloc_chain(0), gc_alloc_chain(0),
dom(dom), dom(dom),
cache(NULL), cache(NULL),
@ -69,13 +69,17 @@ rust_task::rust_task(rust_dom *dom, rust_task_list *state,
supervisor(spawner), supervisor(spawner),
list_index(-1), list_index(-1),
rendezvous_ptr(0), rendezvous_ptr(0),
alarm(this),
handle(NULL), 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); LOGPTR(dom, "new task", (uintptr_t)this);
DLOG(dom, task, "sizeof(task) = %d (0x%x)", sizeof *this, sizeof *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) { if (spawner == NULL) {
ref_count = 0; ref_count = 0;
} }
@ -111,7 +115,7 @@ rust_task::~rust_task()
I(dom, ref_count == 0 || I(dom, ref_count == 0 ||
(ref_count == 1 && this == dom->root_task)); (ref_count == 1 && this == dom->root_task));
del_stk(dom, stk); del_stk(this, stk);
} }
extern "C" void rust_new_exit_task_glue(); extern "C" void rust_new_exit_task_glue();
@ -352,7 +356,7 @@ rust_task::malloc(size_t sz, type_desc *td)
if (td) { if (td) {
sz += sizeof(gc_alloc); sz += sizeof(gc_alloc);
} }
void *mem = dom->malloc(sz); void *mem = malloc(sz, memory_region::LOCAL);
if (!mem) if (!mem)
return mem; return mem;
if (td) { 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)); gc_alloc *gcm = (gc_alloc*)(((char *)data) - sizeof(gc_alloc));
unlink_gc(gcm); unlink_gc(gcm);
sz += sizeof(gc_alloc); 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 DLOG(dom, task, "task %s @0x%" PRIxPTR
" reallocated %d GC bytes = 0x%" PRIxPTR, " reallocated %d GC bytes = 0x%" PRIxPTR,
name, (uintptr_t)this, sz, gcm); name, (uintptr_t)this, sz, gcm);
@ -388,7 +392,7 @@ rust_task::realloc(void *data, size_t sz, bool is_gc)
link_gc(gcm); link_gc(gcm);
data = (void*) &(gcm->data); data = (void*) &(gcm->data);
} else { } else {
data = dom->realloc(data, sz); data = realloc(data, sz, memory_region::LOCAL);
} }
return data; return data;
} }
@ -405,9 +409,9 @@ rust_task::free(void *p, bool is_gc)
DLOG(dom, mem, DLOG(dom, mem,
"task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR, "task %s @0x%" PRIxPTR " freeing GC memory = 0x%" PRIxPTR,
name, (uintptr_t)this, gcm); name, (uintptr_t)this, gcm);
dom->free(gcm); free(gcm, memory_region::LOCAL);
} else { } 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; 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: // Local Variables:
// mode: C++ // mode: C++

View file

@ -9,9 +9,34 @@
#include "context.h" #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 struct
rust_task : public maybe_proxy<rust_task>, rust_task : public maybe_proxy<rust_task>,
public dom_owned<rust_task> public kernel_owned<rust_task>
{ {
// Fields known to the compiler. // Fields known to the compiler.
stk_seg *stk; stk_seg *stk;
@ -46,8 +71,6 @@ rust_task : public maybe_proxy<rust_task>,
// List of tasks waiting for this task to finish. // List of tasks waiting for this task to finish.
array_list<maybe_proxy<rust_task> *> tasks_waiting_to_join; array_list<maybe_proxy<rust_task> *> tasks_waiting_to_join;
rust_alarm alarm;
rust_handle<rust_task> *handle; rust_handle<rust_task> *handle;
context ctx; context ctx;
@ -56,6 +79,9 @@ rust_task : public maybe_proxy<rust_task>,
// or is about to run this task. // or is about to run this task.
volatile bool active; 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. // Only a pointer to 'name' is kept, so it must live as long as this task.
rust_task(rust_dom *dom, rust_task(rust_dom *dom,
rust_task_list *state, rust_task_list *state,
@ -118,6 +144,13 @@ rust_task : public maybe_proxy<rust_task>,
rust_crate_cache * get_crate_cache(); rust_crate_cache * get_crate_cache();
bool can_schedule(); 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);
}; };
// //

View file

@ -1,3 +1,4 @@
// -*- c++-mode -*-
#ifndef RUST_TASK_LIST_H #ifndef RUST_TASK_LIST_H
#define RUST_TASK_LIST_H #define RUST_TASK_LIST_H
@ -5,7 +6,7 @@
* Used to indicate the state of a rust task. * Used to indicate the state of a rust task.
*/ */
class rust_task_list : public indexed_list<rust_task>, class rust_task_list : public indexed_list<rust_task>,
public dom_owned<rust_task_list> { public kernel_owned<rust_task_list> {
public: public:
rust_dom *dom; rust_dom *dom;
const char* name; const char* name;

View file

@ -74,11 +74,10 @@ upcall_trace_str(rust_task *task, char const *c) {
extern "C" CDECL rust_port* extern "C" CDECL rust_port*
upcall_new_port(rust_task *task, size_t unit_sz) { upcall_new_port(rust_task *task, size_t unit_sz) {
LOG_UPCALL_ENTRY(task); LOG_UPCALL_ENTRY(task);
rust_dom *dom = task->dom;
scoped_lock with(task->kernel->scheduler_lock); scoped_lock with(task->kernel->scheduler_lock);
LOG(task, comm, "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)", LOG(task, comm, "upcall_new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)",
(uintptr_t) task, task->name, unit_sz); (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 extern "C" CDECL void
@ -101,7 +100,7 @@ upcall_new_chan(rust_task *task, rust_port *port) {
"task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")", "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")",
(uintptr_t) task, task->name, port); (uintptr_t) task, task->name, port);
I(dom, 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; port = proxy;
target_task = target->as_proxy()->handle()->referent(); 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 extern "C" CDECL void

View file

@ -1,6 +1,8 @@
#ifndef RUST_UTIL_H #ifndef RUST_UTIL_H
#define RUST_UTIL_H #define RUST_UTIL_H
#include "rust_task.h"
// Reference counted objects // Reference counted objects
template <typename T> template <typename T>
@ -17,30 +19,30 @@ rc_base<T>::~rc_base()
// Utility type: pointer-vector. // Utility type: pointer-vector.
template <typename T> template <typename T>
ptr_vec<T>::ptr_vec(rust_dom *dom) : ptr_vec<T>::ptr_vec(rust_task *task) :
dom(dom), task(task),
alloc(INIT_SIZE), alloc(INIT_SIZE),
fill(0), fill(0),
data(new (dom) T*[alloc]) data(new (task) T*[alloc])
{ {
I(dom, data); I(task->dom, data);
DLOG(dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR, DLOG(task->dom, mem, "new ptr_vec(data=0x%" PRIxPTR ") -> 0x%" PRIxPTR,
(uintptr_t)data, (uintptr_t)this); (uintptr_t)data, (uintptr_t)this);
} }
template <typename T> template <typename T>
ptr_vec<T>::~ptr_vec() ptr_vec<T>::~ptr_vec()
{ {
I(dom, data); I(task->dom, data);
DLOG(dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR, DLOG(task->dom, mem, "~ptr_vec 0x%" PRIxPTR ", data=0x%" PRIxPTR,
(uintptr_t)this, (uintptr_t)data); (uintptr_t)this, (uintptr_t)data);
I(dom, fill == 0); I(task->dom, fill == 0);
dom->free(data); task->free(data);
} }
template <typename T> T *& template <typename T> T *&
ptr_vec<T>::operator[](size_t offset) { ptr_vec<T>::operator[](size_t offset) {
I(dom, data[offset]->idx == offset); I(task->dom, data[offset]->idx == offset);
return data[offset]; return data[offset];
} }
@ -48,14 +50,14 @@ template <typename T>
void void
ptr_vec<T>::push(T *p) ptr_vec<T>::push(T *p)
{ {
I(dom, data); I(task->dom, data);
I(dom, fill <= alloc); I(task->dom, fill <= alloc);
if (fill == alloc) { if (fill == alloc) {
alloc *= 2; alloc *= 2;
data = (T **)dom->realloc(data, alloc * sizeof(T*)); data = (T **)task->realloc(data, alloc * sizeof(T*));
I(dom, data); I(task->dom, data);
} }
I(dom, fill < alloc); I(task->dom, fill < alloc);
p->idx = fill; p->idx = fill;
data[fill++] = p; data[fill++] = p;
} }
@ -78,13 +80,13 @@ template <typename T>
void void
ptr_vec<T>::trim(size_t sz) ptr_vec<T>::trim(size_t sz)
{ {
I(dom, data); I(task->dom, data);
if (sz <= (alloc / 4) && if (sz <= (alloc / 4) &&
(alloc / 2) >= INIT_SIZE) { (alloc / 2) >= INIT_SIZE) {
alloc /= 2; alloc /= 2;
I(dom, alloc >= fill); I(task->dom, alloc >= fill);
data = (T **)dom->realloc(data, alloc * sizeof(T*)); data = (T **)task->realloc(data, alloc * sizeof(T*));
I(dom, data); I(task->dom, data);
} }
} }
@ -93,9 +95,9 @@ void
ptr_vec<T>::swap_delete(T *item) ptr_vec<T>::swap_delete(T *item)
{ {
/* Swap the endpoint into i and decr fill. */ /* Swap the endpoint into i and decr fill. */
I(dom, data); I(task->dom, data);
I(dom, fill > 0); I(task->dom, fill > 0);
I(dom, item->idx < fill); I(task->dom, item->idx < fill);
fill--; fill--;
if (fill > 0) { if (fill > 0) {
T *subst = data[fill]; T *subst = data[fill];
@ -155,7 +157,8 @@ isaac_init(rust_dom *dom, randctx *rctx)
} else { } else {
int fd = open("/dev/urandom", O_RDONLY); int fd = open("/dev/urandom", O_RDONLY);
I(dom, fd > 0); 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)); == sizeof(rctx->randrsl));
I(dom, close(fd) == 0); I(dom, close(fd) == 0);
} }

View file

@ -2,6 +2,8 @@
// xfail-stage0 // xfail-stage0
// xfail-stage1
// xfail-stage2
// Reported as issue #126, child leaks the string. // Reported as issue #126, child leaks the string.
fn child2(str s) { } fn child2(str s) { }

View file

@ -5,6 +5,8 @@
*/ */
// xfail-stage0 // xfail-stage0
// xfail-stage1
// xfail-stage2
use std; use std;

View file

@ -1,4 +1,6 @@
// xfail-stage0 // xfail-stage0
// xfail-stage1
// xfail-stage2
fn main() -> () { fn main() -> () {
spawn child("Hello"); spawn child("Hello");
} }