Skip to content

Commit

Permalink
Lots of design changes around proxies and message passing. Made it so…
Browse files Browse the repository at this point in the history
… that domains can only talk to other domains via handles, and with the help of the rust_kernel.
  • Loading branch information
mbebenita committed Sep 8, 2010
1 parent a6aebda commit de611a3
Show file tree
Hide file tree
Showing 23 changed files with 643 additions and 437 deletions.
30 changes: 4 additions & 26 deletions src/Makefile
Expand Up @@ -380,33 +380,10 @@ self: $(CFG_COMPILER)
# Temporarily xfail the entire multi-tasking system, pending resolution
# of inter-task shutdown races introduced with notification proxies.

TASK_XFAILS := test/run-pass/acyclic-unwind.rs \
test/run-pass/alt-type-simple.rs \
test/run-pass/basic.rs \
test/run-pass/clone-with-exterior.rs \
test/run-pass/comm.rs \
test/run-pass/lazychan.rs \
test/run-pass/many.rs \
test/run-pass/obj-dtor.rs \
test/run-pass/preempt.rs \
test/run-pass/spawn-fn.rs \
test/run-pass/spawn-module-qualified.rs \
test/run-pass/spawn.rs \
test/run-pass/task-comm-0.rs \
test/run-pass/task-comm-1.rs \
test/run-pass/task-comm-2.rs \
test/run-pass/task-comm-3.rs \
test/run-pass/task-comm-7.rs \
test/run-pass/task-comm-8.rs \
test/run-pass/task-comm-9.rs \
test/run-pass/task-comm-10.rs \
test/run-pass/task-comm-11.rs \
test/run-pass/task-life-0.rs \
test/run-pass/task-comm.rs \
test/run-pass/threads.rs \
test/run-pass/yield.rs \
TASK_XFAILS := test/run-pass/task-comm-10.rs \
test/run-pass/task-comm-15.rs \
test/run-pass/task-life-0.rs
test/run-pass/task-life-0.rs \
test/run-pass/alt-type-simple.rs

TEST_XFAILS_X86 := $(TASK_XFAILS) \
test/run-pass/child-outlives-parent.rs \
Expand All @@ -425,6 +402,7 @@ TEST_XFAILS_X86 := $(TASK_XFAILS) \
test/run-pass/task-comm.rs \
test/run-pass/vec-slice.rs \
test/run-pass/task-comm-3.rs \
test/run-fail/task-comm-14.rs \
test/compile-fail/bad-recv.rs \
test/compile-fail/bad-send.rs \
test/compile-fail/infinite-tag-type-recursion.rs \
Expand Down
2 changes: 1 addition & 1 deletion src/boot/be/abi.ml
Expand Up @@ -20,7 +20,7 @@ let task_field_gc_alloc_chain = task_field_rust_sp + 1;;
let task_field_dom = task_field_gc_alloc_chain + 1;;
let n_visible_task_fields = task_field_dom + 1;;

let dom_field_interrupt_flag = 0;;
let dom_field_interrupt_flag = 1;;

let frame_glue_fns_field_mark = 0;;
let frame_glue_fns_field_drop = 1;;
Expand Down
5 changes: 0 additions & 5 deletions src/rt/memory.h
@@ -1,11 +1,6 @@
/*
*
*/

#ifndef MEMORY_H
#define MEMORY_H


inline void *operator new(size_t size, void *mem) {
return mem;
}
Expand Down
7 changes: 2 additions & 5 deletions src/rt/memory_region.cpp
@@ -1,7 +1,3 @@
/*
*
*/

#include "rust_internal.h"
#include "memory_region.h"

Expand All @@ -20,6 +16,7 @@ memory_region::memory_region(memory_region *parent) :
}

void memory_region::free(void *mem) {
// printf("free: ptr 0x%" PRIxPTR"\n", (uintptr_t) mem);
if (_synchronized) { _lock.lock(); }
#ifdef TRACK_ALLOCATIONS
if (_allocation_list.replace(mem, NULL) == false) {
Expand All @@ -34,7 +31,6 @@ void memory_region::free(void *mem) {
_live_allocations--;
_srv->free(mem);
if (_synchronized) { _lock.unlock(); }

}

void *
Expand Down Expand Up @@ -63,6 +59,7 @@ memory_region::malloc(size_t size) {
#ifdef TRACK_ALLOCATIONS
_allocation_list.append(mem);
#endif
// printf("malloc: ptr 0x%" PRIxPTR "\n", (uintptr_t) mem);
if (_synchronized) { _lock.unlock(); }
return mem;
}
Expand Down
85 changes: 45 additions & 40 deletions src/rt/rust.cpp
@@ -1,16 +1,16 @@
#include "rust_internal.h"

struct
command_line_args
command_line_args : public dom_owned<command_line_args>
{
rust_dom &dom;
rust_dom *dom;
int argc;
char **argv;

// vec[str] passed to rust_task::start.
rust_vec *args;

command_line_args(rust_dom &dom,
command_line_args(rust_dom *dom,
int sys_argc,
char **sys_argv)
: dom(dom),
Expand All @@ -21,29 +21,29 @@ command_line_args
#if defined(__WIN32__)
LPCWSTR cmdline = GetCommandLineW();
LPWSTR *wargv = CommandLineToArgvW(cmdline, &argc);
dom.win32_require("CommandLineToArgvW", wargv != NULL);
argv = (char **) dom.malloc(sizeof(char*) * argc);
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,
NULL, 0, NULL, NULL);
dom.win32_require("WideCharToMultiByte(0)", n_chars != 0);
argv[i] = (char *) dom.malloc(n_chars);
dom->win32_require("WideCharToMultiByte(0)", n_chars != 0);
argv[i] = (char *) dom->malloc(n_chars);
n_chars = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1,
argv[i], n_chars, NULL, NULL);
dom.win32_require("WideCharToMultiByte(1)", n_chars != 0);
dom->win32_require("WideCharToMultiByte(1)", n_chars != 0);
}
LocalFree(wargv);
#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 = dom->malloc(vec_alloc);
args = new (mem) rust_vec(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 = dom->malloc(str_alloc);
strs[i] = new (mem) rust_str(dom, str_alloc, str_fill,
(uint8_t const *)argv[i]);
}
args->fill = vec_fill;
Expand All @@ -58,50 +58,55 @@ 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);
dom->free(strs[i]);
dom->free(args);
}

#ifdef __WIN32__
for (int i = 0; i < argc; ++i) {
dom.free(argv[i]);
dom->free(argv[i]);
}
dom.free(argv);
dom->free(argv);
#endif
}
};

/**
* Main entry point into the Rust runtime. Here we create a Rust service,
* initialize the kernel, create the root domain and run it.
*/

extern "C" CDECL int
rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv)
{
int ret;
{
rust_srv srv;
rust_dom dom(&srv, crate, "main");
srv.kernel->register_domain(&dom);
command_line_args args(dom, argc, argv);
rust_start(uintptr_t main_fn, rust_crate const *crate, int argc,
char **argv) {

dom.log(rust_log::DOM, "startup: %d args", args.argc);
for (int i = 0; i < args.argc; ++i)
dom.log(rust_log::DOM,
"startup: arg[%d] = '%s'", i, args.argv[i]);

if (dom._log.is_tracing(rust_log::DWARF)) {
rust_crate_reader rdr(&dom, crate);
}
rust_srv *srv = new rust_srv();
rust_kernel *kernel = new rust_kernel(srv);
kernel->start();
rust_handle<rust_dom> *handle = kernel->create_domain(crate, "main");
rust_dom *dom = handle->referent();
command_line_args *args = new (dom) command_line_args(dom, argc, argv);

uintptr_t main_args[4] = { 0, 0, 0, (uintptr_t)args.args };

dom.root_task->start(crate->get_exit_task_glue(),
main_fn,
(uintptr_t)&main_args,
sizeof(main_args));
dom->log(rust_log::DOM, "startup: %d args", args->argc);
for (int i = 0; i < args->argc; i++) {
dom->log(rust_log::DOM,
"startup: arg[%d] = '%s'", i, args->argv[i]);
}

ret = dom.start_main_loop();
srv.kernel->deregister_domain(&dom);
if (dom->_log.is_tracing(rust_log::DWARF)) {
rust_crate_reader create_reader(dom, crate);
}

uintptr_t main_args[4] = {0, 0, 0, (uintptr_t)args->args};
dom->root_task->start(crate->get_exit_task_glue(),
main_fn, (uintptr_t)&main_args, sizeof(main_args));
int ret = dom->start_main_loop();
delete args;
kernel->destroy_domain(dom);
kernel->join_all_domains();
delete kernel;
delete srv;

#if !defined(__WIN32__)
// Don't take down the process if the main thread exits without an
// error.
Expand Down
25 changes: 12 additions & 13 deletions src/rt/rust_chan.cpp
Expand Up @@ -4,13 +4,15 @@
/**
* Create a new rust channel and associate it with the specified port.
*/
rust_chan::rust_chan(rust_task *task, maybe_proxy<rust_port> *port) :
task(task), port(port), buffer(task->dom, port->delegate()->unit_sz) {

rust_chan::rust_chan(rust_task *task,
maybe_proxy<rust_port> *port,
size_t unit_sz) :
task(task),
port(port),
buffer(task->dom, unit_sz) {
if (port) {
associate(port);
}

task->log(rust_log::MEM | rust_log::COMM,
"new rust_chan(task=0x%" PRIxPTR
", port=0x%" PRIxPTR ") -> chan=0x%" PRIxPTR,
Expand All @@ -34,7 +36,7 @@ void rust_chan::associate(maybe_proxy<rust_port> *port) {
task->log(rust_log::TASK,
"associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
this, port);
this->port->delegate()->chans.push(this);
this->port->referent()->chans.push(this);
}
}

Expand All @@ -51,8 +53,8 @@ void rust_chan::disassociate() {
if (port->is_proxy() == false) {
task->log(rust_log::TASK,
"disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
this, port->delegate());
port->delegate()->chans.swap_delete(this);
this, port->referent());
port->referent()->chans.swap_delete(this);
}

// Delete reference to the port.
Expand All @@ -76,14 +78,11 @@ void rust_chan::send(void *sptr) {
"rust_chan::transmit with nothing to send.");

if (port->is_proxy()) {
// TODO: Cache port task locally.
rust_proxy<rust_task> *port_task =
dom->get_task_proxy(port->delegate()->task);
data_message::send(buffer.peek(), buffer.unit_sz,
"send data", task, port_task, port->as_proxy());
data_message::send(buffer.peek(), buffer.unit_sz, "send data",
task->get_handle(), port->as_proxy()->handle());
buffer.dequeue(NULL);
} else {
rust_port *target_port = port->delegate();
rust_port *target_port = port->referent();
if (target_port->task->blocked_on(target_port)) {
dom->log(rust_log::COMM, "dequeued in rendezvous_ptr");
buffer.dequeue(target_port->task->rendezvous_ptr);
Expand Down
3 changes: 2 additions & 1 deletion src/rt/rust_chan.h
Expand Up @@ -5,7 +5,8 @@ class rust_chan : public rc_base<rust_chan>,
public task_owned<rust_chan>,
public rust_cond {
public:
rust_chan(rust_task *task, maybe_proxy<rust_port> *port);
rust_chan(rust_task *task, maybe_proxy<rust_port> *port, size_t unit_sz);

~rust_chan();

rust_task *task;
Expand Down

0 comments on commit de611a3

Please sign in to comment.