2010-07-19 16:05:18 -05:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef RUST_TASK_H
|
|
|
|
#define RUST_TASK_H
|
2010-07-28 18:24:50 -05:00
|
|
|
|
|
|
|
#include "util/array_list.h"
|
|
|
|
|
2011-05-31 19:44:54 -05:00
|
|
|
#include "context.h"
|
|
|
|
|
2011-06-27 21:15:03 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
struct
|
2011-07-27 16:51:25 -05:00
|
|
|
rust_task : public kernel_owned<rust_task>, rust_cond
|
2010-07-19 16:05:18 -05:00
|
|
|
{
|
2011-08-05 17:16:48 -05:00
|
|
|
RUST_ATOMIC_REFCOUNT();
|
2011-07-27 16:51:25 -05:00
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
// Fields known to the compiler.
|
|
|
|
stk_seg *stk;
|
|
|
|
uintptr_t runtime_sp; // Runtime sp while task running.
|
|
|
|
uintptr_t rust_sp; // Saved sp when not running.
|
|
|
|
gc_alloc *gc_alloc_chain; // Linked list of GC allocations.
|
2011-06-28 14:15:41 -05:00
|
|
|
rust_scheduler *sched;
|
2010-07-19 16:05:18 -05:00
|
|
|
rust_crate_cache *cache;
|
|
|
|
|
|
|
|
// Fields known only to the runtime.
|
2011-06-24 18:50:06 -05:00
|
|
|
rust_kernel *kernel;
|
2010-08-08 21:24:35 -05:00
|
|
|
const char *const name;
|
2010-09-10 03:21:29 -05:00
|
|
|
rust_task_list *state;
|
2010-07-19 16:05:18 -05:00
|
|
|
rust_cond *cond;
|
2010-08-18 01:26:43 -05:00
|
|
|
const char *cond_name;
|
2010-07-19 16:05:18 -05:00
|
|
|
rust_task *supervisor; // Parent-link for failure propagation.
|
2010-09-10 03:21:29 -05:00
|
|
|
int32_t list_index;
|
2010-07-19 16:05:18 -05:00
|
|
|
size_t gc_alloc_thresh;
|
|
|
|
size_t gc_alloc_accum;
|
|
|
|
|
2011-08-08 15:38:20 -05:00
|
|
|
rust_task_id id;
|
2011-08-08 20:09:42 -05:00
|
|
|
rust_port_id next_port_id;
|
2011-08-08 15:38:20 -05:00
|
|
|
|
2010-08-11 23:23:34 -05:00
|
|
|
// Keeps track of the last time this task yielded.
|
|
|
|
timer yield_timer;
|
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
// Rendezvous pointer for receiving data when blocked on a port. If we're
|
|
|
|
// trying to read data and no data is available on any incoming channel,
|
|
|
|
// we block on the port, and yield control to the scheduler. Since, we
|
2010-07-28 14:36:59 -05:00
|
|
|
// were not able to read anything, we remember the location where the
|
2010-07-19 16:05:18 -05:00
|
|
|
// result should go in the rendezvous_ptr, and let the sender write to
|
|
|
|
// that location before waking us up.
|
|
|
|
uintptr_t* rendezvous_ptr;
|
|
|
|
|
2010-07-28 18:24:50 -05:00
|
|
|
// List of tasks waiting for this task to finish.
|
2011-07-27 16:51:25 -05:00
|
|
|
array_list<rust_task *> tasks_waiting_to_join;
|
2010-07-28 18:24:50 -05:00
|
|
|
|
2011-05-31 19:44:54 -05:00
|
|
|
context ctx;
|
2011-07-13 17:44:09 -05:00
|
|
|
|
2011-06-20 19:19:50 -05:00
|
|
|
// This flag indicates that a worker is either currently running the task
|
|
|
|
// or is about to run this task.
|
2011-06-29 20:47:47 -05:00
|
|
|
int running_on;
|
|
|
|
int pinned_on;
|
2011-05-31 19:44:54 -05:00
|
|
|
|
2011-06-27 21:15:03 -05:00
|
|
|
memory_region local_region;
|
|
|
|
|
2011-07-06 13:10:40 -05:00
|
|
|
class wakeup_callback {
|
|
|
|
public:
|
|
|
|
virtual void on_wakeup() = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
wakeup_callback *_on_wakeup;
|
|
|
|
|
2011-07-14 21:39:53 -05:00
|
|
|
// Indicates that the task ended in failure
|
|
|
|
bool failed;
|
2011-07-23 21:03:02 -05:00
|
|
|
bool propagate_failure;
|
2011-07-14 21:39:53 -05:00
|
|
|
|
2011-07-07 13:53:08 -05:00
|
|
|
lock_and_signal lock;
|
|
|
|
|
2011-08-08 20:09:42 -05:00
|
|
|
hash_map<rust_port_id, rust_port *> port_table;
|
|
|
|
|
2010-08-08 21:24:35 -05:00
|
|
|
// Only a pointer to 'name' is kept, so it must live as long as this task.
|
2011-06-28 14:15:41 -05:00
|
|
|
rust_task(rust_scheduler *sched,
|
2010-09-10 03:21:29 -05:00
|
|
|
rust_task_list *state,
|
2010-08-08 21:24:35 -05:00
|
|
|
rust_task *spawner,
|
|
|
|
const char *name);
|
2010-09-07 20:39:07 -05:00
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
~rust_task();
|
|
|
|
|
2011-05-24 14:51:22 -05:00
|
|
|
void start(uintptr_t spawnee_fn,
|
2011-06-15 20:16:17 -05:00
|
|
|
uintptr_t args);
|
2011-08-10 20:48:57 -05:00
|
|
|
void start();
|
2010-07-19 16:05:18 -05:00
|
|
|
void grow(size_t n_frame_bytes);
|
|
|
|
bool running();
|
|
|
|
bool blocked();
|
|
|
|
bool blocked_on(rust_cond *cond);
|
|
|
|
bool dead();
|
|
|
|
|
|
|
|
void link_gc(gc_alloc *gcm);
|
|
|
|
void unlink_gc(gc_alloc *gcm);
|
2011-07-18 14:02:26 -05:00
|
|
|
void *malloc(size_t sz, const char *tag, type_desc *td=0);
|
2010-07-19 16:05:18 -05:00
|
|
|
void *realloc(void *data, size_t sz, bool gc_mem=false);
|
|
|
|
void free(void *p, bool gc_mem=false);
|
|
|
|
|
2010-09-10 03:21:29 -05:00
|
|
|
void transition(rust_task_list *src, rust_task_list *dst);
|
2010-07-19 16:05:18 -05:00
|
|
|
|
2010-08-18 01:26:43 -05:00
|
|
|
void block(rust_cond *on, const char* name);
|
2010-07-19 16:05:18 -05:00
|
|
|
void wakeup(rust_cond *from);
|
|
|
|
void die();
|
|
|
|
void unblock();
|
|
|
|
|
2010-10-11 18:40:18 -05:00
|
|
|
// Print a backtrace, if the "bt" logging option is on.
|
|
|
|
void backtrace();
|
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
// Save callee-saved registers and return to the main loop.
|
2011-07-13 15:43:35 -05:00
|
|
|
void yield();
|
2010-07-19 16:05:18 -05:00
|
|
|
|
2010-08-11 23:23:34 -05:00
|
|
|
// Yields for a specified duration of time.
|
2011-07-13 15:43:35 -05:00
|
|
|
void yield(size_t time_in_ms);
|
2010-08-11 23:23:34 -05:00
|
|
|
|
2010-07-19 16:05:18 -05:00
|
|
|
// Fail this task (assuming caller-on-stack is different task).
|
|
|
|
void kill();
|
|
|
|
|
|
|
|
// Fail self, assuming caller-on-stack is this task.
|
2011-07-13 15:43:35 -05:00
|
|
|
void fail();
|
2010-07-19 16:05:18 -05:00
|
|
|
|
|
|
|
// Run the gc glue on the task stack.
|
2011-07-13 15:43:35 -05:00
|
|
|
void gc();
|
2010-07-19 16:05:18 -05:00
|
|
|
|
|
|
|
// Disconnect from our supervisor.
|
|
|
|
void unsupervise();
|
|
|
|
|
|
|
|
// Notify tasks waiting for us that we are about to die.
|
2010-07-28 18:24:50 -05:00
|
|
|
void notify_tasks_waiting_to_join();
|
2010-07-19 16:05:18 -05:00
|
|
|
|
|
|
|
frame_glue_fns *get_frame_glue_fns(uintptr_t fp);
|
2011-05-26 20:20:48 -05:00
|
|
|
rust_crate_cache * get_crate_cache();
|
2011-06-20 19:19:50 -05:00
|
|
|
|
2011-06-29 20:47:47 -05:00
|
|
|
bool can_schedule(int worker);
|
2011-06-27 21:15:03 -05:00
|
|
|
|
2011-07-18 14:02:26 -05:00
|
|
|
void *calloc(size_t size, const char *tag);
|
2011-06-29 20:47:47 -05:00
|
|
|
|
|
|
|
void pin();
|
2011-06-29 20:56:34 -05:00
|
|
|
void pin(int id);
|
2011-06-29 20:47:47 -05:00
|
|
|
void unpin();
|
2011-07-06 13:10:40 -05:00
|
|
|
|
|
|
|
void on_wakeup(wakeup_callback *callback);
|
2011-08-08 20:09:42 -05:00
|
|
|
|
|
|
|
rust_port_id register_port(rust_port *port);
|
|
|
|
void release_port(rust_port_id id);
|
|
|
|
rust_port *get_port_by_id(rust_port_id id);
|
2010-07-19 16:05:18 -05:00
|
|
|
};
|
|
|
|
|
2010-07-28 02:36:35 -05:00
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: C++
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
2011-07-13 15:51:20 -05:00
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
2010-07-28 02:36:35 -05:00
|
|
|
// End:
|
|
|
|
//
|
2010-07-19 16:05:18 -05:00
|
|
|
|
|
|
|
#endif /* RUST_TASK_H */
|