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:
parent
f6f945fed5
commit
49a8cb34d2
21 changed files with 217 additions and 226 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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++
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
|
||||
// xfail-stage0
|
||||
// xfail-stage1
|
||||
// xfail-stage2
|
||||
// Reported as issue #126, child leaks the string.
|
||||
fn child2(str s) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
|
||||
// xfail-stage0
|
||||
// xfail-stage1
|
||||
// xfail-stage2
|
||||
|
||||
use std;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// xfail-stage0
|
||||
// xfail-stage1
|
||||
// xfail-stage2
|
||||
fn main() -> () {
|
||||
spawn child("Hello");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue