Skip to content

Commit

Permalink
Added a few utility classes, cleaned up the include order of .h files…
Browse files Browse the repository at this point in the history
…, and started to make the Rust kernel own domain message queues rather than the Rust domains themselves.
  • Loading branch information
mbebenita committed Sep 8, 2010
1 parent ffdb5fc commit f8ff013
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 111 deletions.
4 changes: 4 additions & 0 deletions src/Makefile
Expand Up @@ -267,6 +267,7 @@ RUNTIME_CS := rt/sync/timer.cpp \
rt/circular_buffer.cpp \
rt/isaac/randport.cpp \
rt/rust_srv.cpp \
rt/rust_kernel.cpp \
rt/memory_region.cpp

RUNTIME_HDR := rt/globals.h \
Expand All @@ -283,11 +284,14 @@ RUNTIME_HDR := rt/globals.h \
rt/rust_message.h \
rt/circular_buffer.h \
rt/util/array_list.h \
rt/util/indexed_list.h \
rt/util/synchronized_indexed_list.h \
rt/util/hash_map.h \
rt/sync/sync.h \
rt/sync/timer.h \
rt/sync/lock_free_queue.h \
rt/rust_srv.h \
rt/rust_kernel.h \
rt/memory_region.h \
rt/memory.h

Expand Down
3 changes: 2 additions & 1 deletion src/rt/rust.cpp
@@ -1,6 +1,5 @@
#include "rust_internal.h"


struct
command_line_args
{
Expand Down Expand Up @@ -80,6 +79,7 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv)
{
rust_srv srv;
rust_dom dom(&srv, crate, "main");
srv.kernel->register_domain(&dom);
command_line_args args(dom, argc, argv);

dom.log(rust_log::DOM, "startup: %d args", args.argc);
Expand All @@ -99,6 +99,7 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv)
sizeof(main_args));

ret = dom.start_main_loop();
srv.kernel->deregister_domain(&dom);
}

#if !defined(__WIN32__)
Expand Down
4 changes: 0 additions & 4 deletions src/rt/rust.h
Expand Up @@ -17,10 +17,6 @@
#define CDECL
#endif

#include "util/array_list.h"

#include "rust_srv.h"

/*
* Local Variables:
* fill-column: 78;
Expand Down
23 changes: 4 additions & 19 deletions src/rt/rust_dom.cpp
Expand Up @@ -4,9 +4,6 @@

template class ptr_vec<rust_task>;

// Keeps track of all live domains, for debugging purposes.
array_list<rust_dom*> _live_domains;

rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate,
const char *name) :
interrupt_flag(0),
Expand All @@ -22,7 +19,8 @@ rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate,
caches(this),
root_task(NULL),
curr_task(NULL),
rval(0)
rval(0),
_kernel(srv->kernel)
{
logptr("new dom", (uintptr_t)this);
isaac_init(this, &rctx);
Expand All @@ -32,10 +30,6 @@ rust_dom::rust_dom(rust_srv *srv, rust_crate const *root_crate,
pthread_attr_setdetachstate(&attr, true);
#endif
root_task = new (this) rust_task(this, NULL, name);

if (_live_domains.replace(NULL, this) == false) {
_live_domains.append(this);
}
}

static void
Expand Down Expand Up @@ -86,8 +80,6 @@ rust_dom::~rust_dom() {
#endif
while (caches.length())
delete caches.pop();

_live_domains.replace(this, NULL);
}

void
Expand Down Expand Up @@ -375,7 +367,7 @@ rust_dom::schedule_task() {
*/
bool
rust_dom::is_deadlocked() {
if (_live_domains.size() != 1) {
if (_kernel->domains.length() != 1) {
// We cannot tell if we are deadlocked if other domains exists.
return false;
}
Expand All @@ -388,20 +380,13 @@ rust_dom::is_deadlocked() {
if (_incoming_message_queue.is_empty() && blocked_tasks.length() > 0) {
// We have no messages to process, no running tasks to schedule
// and some blocked tasks therefore we are likely in a deadlock.
log_state();
_kernel->log_all_domain_state();
return true;
}

return false;
}

void
rust_dom::log_all_state() {
for (uint32_t i = 0; i < _live_domains.size(); i++) {
_live_domains[i]->log_state();
}
}

void
rust_dom::log_state() {
if (!running_tasks.is_empty()) {
Expand Down
13 changes: 3 additions & 10 deletions src/rt/rust_dom.h
@@ -1,16 +1,6 @@
/*
* rust_dom.h
*/

#ifndef RUST_DOM_H
#define RUST_DOM_H

#include "sync/lock_free_queue.h"
#include "util/hash_map.h"

#include "rust_proxy.h"
#include "rust_message.h"

struct rust_dom
{
// Fields known to the compiler:
Expand All @@ -37,6 +27,9 @@ struct rust_dom
rust_task *curr_task;
int rval;

rust_kernel *_kernel;
int32_t list_index;

hash_map<rust_task *, rust_proxy<rust_task> *> _task_proxies;
hash_map<rust_port *, rust_proxy<rust_port> *> _port_proxies;

Expand Down
91 changes: 35 additions & 56 deletions src/rt/rust_internal.h
Expand Up @@ -14,11 +14,8 @@

#include <stdio.h>
#include <string.h>

#include "rust.h"

#include "rand.h"
#include "rust_log.h"
#include "uthash.h"

#if defined(__WIN32__)
Expand All @@ -39,9 +36,28 @@ extern "C" {
#error "Platform not supported."
#endif

#include "util/array_list.h"
#include "util/indexed_list.h"
#include "util/synchronized_indexed_list.h"
#include "util/hash_map.h"
#include "sync/sync.h"
#include "sync/timer.h"
#include "sync/condition_variable.h"
#include "sync/lock_free_queue.h"

class rust_dom;
class rust_log;
class rust_task;
class rust_port;
class rust_chan;
struct rust_token;
class rust_kernel;
class rust_crate;
class rust_crate_cache;

struct stk_seg;
struct type_desc;
struct frame_glue_fns;

#ifndef __i386__
#error "Target CPU not supported."
Expand All @@ -56,29 +72,13 @@ extern "C" {
#define A(dom, e, s, ...) ((e) ? (void)0 : \
(dom)->srv->fatal(#e, __FILE__, __LINE__, s, ## __VA_ARGS__))

struct rust_task;
struct rust_port;
class rust_chan;
struct rust_token;
struct rust_dom;
class rust_crate;
class rust_crate_cache;
// class lockfree_queue;

struct stk_seg;
struct type_desc;
struct frame_glue_fns;

// This drives our preemption scheme.

static size_t const TIME_SLICE_IN_MS = 10;

// Every reference counted object should derive from this base class.

template <typename T>
struct
rc_base
{
template <typename T> struct rc_base {
intptr_t ref_count;

void ref() {
Expand All @@ -91,29 +91,25 @@ rc_base
}
}

rc_base();
~rc_base();
rc_base();
~rc_base();
};

template <typename T>
struct
dom_owned
{
template <typename T> struct dom_owned {
rust_dom *get_dom() const {
return ((T*)this)->dom;
}

void operator delete(void *ptr) {
((T *)ptr)->dom->free(ptr);
}
};

template <typename T>
struct
task_owned
{
template <typename T> struct task_owned {
rust_dom *get_dom() const {
return ((T *)this)->task->dom;
}

void operator delete(void *ptr) {
((T *)ptr)->task->dom->free(ptr);
}
Expand All @@ -122,24 +118,16 @@ task_owned
// A cond(ition) is something we can block on. This can be a channel
// (writing), a port (reading) or a task (waiting).

struct
rust_cond
{
};
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 dom_owned<ptr_vec<T> > {
static const size_t INIT_SIZE = 8;

rust_dom *dom;
size_t alloc;
size_t fill;
T **data;

public:
ptr_vec(rust_dom *dom);
~ptr_vec();
Expand All @@ -160,24 +148,16 @@ ptr_vec : public dom_owned<ptr_vec<T> >
void swap_delete(T* p);
};

#include "memory_region.h"
#include "rust_srv.h"
#include "rust_log.h"
#include "rust_proxy.h"
#include "rust_message.h"
#include "rust_kernel.h"
#include "rust_dom.h"

template <typename T> inline T
check_null(rust_dom *dom, T value, char const *expr,
char const *file, size_t line) {
if (value == NULL) {
dom->srv->fatal(expr, file, line, "is null");
}
return value;
}

#define CHECK_NULL(dom, e) (check_null(dom, e, #e, __FILE__, __LINE__))

#include "memory.h"

struct
rust_timer
{
struct rust_timer {
// FIXME: This will probably eventually need replacement
// with something more sophisticated and integrated with
// an IO event-handling library, when we have such a thing.
Expand Down Expand Up @@ -568,7 +548,6 @@ struct gc_alloc {
};

#include "circular_buffer.h"
#include "rust_proxy.h"
#include "rust_task.h"
#include "rust_chan.h"
#include "rust_port.h"
Expand Down
43 changes: 43 additions & 0 deletions src/rt/rust_kernel.cpp
@@ -0,0 +1,43 @@
#include "rust_internal.h"

rust_kernel::rust_kernel(rust_srv *srv) :
_region(srv->local_region),
_log(srv, NULL),
domains(srv->local_region),
message_queues(srv->local_region) {
// Nop.
}

rust_kernel::~rust_kernel() {
// Nop.
}

void
rust_kernel::register_domain(rust_dom *dom) {
domains.append(dom);
}

void
rust_kernel::deregister_domain(rust_dom *dom) {
domains.remove(dom);
}

void
rust_kernel::log_all_domain_state() {
log(rust_log::KERN, "log_all_domain_state: %d domains", domains.length());
for (uint32_t i = 0; i < domains.length(); i++) {
domains[i]->log_state();
}
}

void
rust_kernel::log(uint32_t type_bits, char const *fmt, ...) {
char buf[256];
if (_log.is_tracing(type_bits)) {
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
_log.trace_ln(NULL, type_bits, buf);
va_end(args);
}
}
21 changes: 21 additions & 0 deletions src/rt/rust_kernel.h
@@ -0,0 +1,21 @@
#ifndef RUST_KERNEL_H
#define RUST_KERNEL_H

/**
* A global object shared by all domains.
*/
class rust_kernel {
memory_region &_region;
rust_log _log;
public:
synchronized_indexed_list<rust_dom> domains;
synchronized_indexed_list<lock_free_queue<rust_message*> > message_queues;
rust_kernel(rust_srv *srv);
void register_domain(rust_dom *dom);
void deregister_domain(rust_dom *dom);
void log_all_domain_state();
void log(uint32_t type_bits, char const *fmt, ...);
virtual ~rust_kernel();
};

#endif /* RUST_KERNEL_H */

0 comments on commit f8ff013

Please sign in to comment.