Properly ref counting to fix valgrind issues on linux.
This commit is contained in:
parent
aa0a51a7f5
commit
d63f8340a5
7 changed files with 44 additions and 15 deletions
|
@ -16,6 +16,7 @@ native "rust" mod rustrt {
|
||||||
fn set_min_stack(stack_size: uint);
|
fn set_min_stack(stack_size: uint);
|
||||||
|
|
||||||
fn new_task() -> task_id;
|
fn new_task() -> task_id;
|
||||||
|
fn drop_task(id : task_id);
|
||||||
fn get_task_pointer(id : task_id) -> *rust_task;
|
fn get_task_pointer(id : task_id) -> *rust_task;
|
||||||
fn get_task_context(id : task_id) -> *x86_registers;
|
fn get_task_context(id : task_id) -> *x86_registers;
|
||||||
fn start_task(id : task_id);
|
fn start_task(id : task_id);
|
||||||
|
@ -114,6 +115,11 @@ fn _spawn(thunk : fn() -> ()) -> task_id {
|
||||||
|
|
||||||
rustrt::leak(thunk);
|
rustrt::leak(thunk);
|
||||||
|
|
||||||
|
// Drop twice because get_task_context and get_task_pounter both bump the
|
||||||
|
// ref count and expect us to free it.
|
||||||
|
rustrt::drop_task(id);
|
||||||
|
rustrt::drop_task(id);
|
||||||
|
|
||||||
ret id;
|
ret id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// NB: please do not commit code with this uncommented. It's
|
// NB: please do not commit code with this uncommented. It's
|
||||||
// hugely expensive and should only be used as a last resort.
|
// hugely expensive and should only be used as a last resort.
|
||||||
//
|
//
|
||||||
#define TRACK_ALLOCATIONS
|
// #define TRACK_ALLOCATIONS
|
||||||
|
|
||||||
#define MAGIC 0xbadc0ffe
|
#define MAGIC 0xbadc0ffe
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,8 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
|
||||||
}
|
}
|
||||||
|
|
||||||
root_task->start(main_fn, (uintptr_t)args->args);
|
root_task->start(main_fn, (uintptr_t)args->args);
|
||||||
|
root_task->deref();
|
||||||
|
root_task = NULL;
|
||||||
|
|
||||||
int ret = kernel->start_task_threads();
|
int ret = kernel->start_task_threads();
|
||||||
delete args;
|
delete args;
|
||||||
|
|
|
@ -303,8 +303,10 @@ task_join(rust_task *task, rust_task_id tid) {
|
||||||
join_task->lock.unlock();
|
join_task->lock.unlock();
|
||||||
}
|
}
|
||||||
if (!join_task->failed) {
|
if (!join_task->failed) {
|
||||||
|
join_task->deref();
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
join_task->deref();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -728,16 +730,27 @@ get_task_context(rust_task *task, rust_task_id id) {
|
||||||
return regs;
|
return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL void
|
||||||
|
drop_task(rust_task *task, rust_task_id tid) {
|
||||||
|
rust_task *target = task->kernel->get_task_by_id(tid);
|
||||||
|
if(target) {
|
||||||
|
target->deref();
|
||||||
|
// Deref twice because get_task_by_id does once.
|
||||||
|
target->deref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" CDECL rust_task *
|
extern "C" CDECL rust_task *
|
||||||
get_task_pointer(rust_task *task, rust_task_id id) {
|
get_task_pointer(rust_task *task, rust_task_id id) {
|
||||||
return task->kernel->get_task_by_id(id);
|
rust_task *t = task->kernel->get_task_by_id(id);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
start_task(rust_task *task, rust_task_id id) {
|
start_task(rust_task *task, rust_task_id id) {
|
||||||
rust_task * target = task->kernel->get_task_by_id(id);
|
rust_task * target = task->kernel->get_task_by_id(id);
|
||||||
|
|
||||||
target->start();
|
target->start();
|
||||||
|
target->deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void *task_trampoline asm("task_trampoline");
|
extern "C" void *task_trampoline asm("task_trampoline");
|
||||||
|
@ -754,6 +767,7 @@ migrate_alloc(rust_task *task, void *alloc, rust_task_id tid) {
|
||||||
if(target) {
|
if(target) {
|
||||||
task->local_region.release_alloc(alloc);
|
task->local_region.release_alloc(alloc);
|
||||||
target->local_region.claim_alloc(alloc);
|
target->local_region.claim_alloc(alloc);
|
||||||
|
target->deref();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We couldn't find the target. Maybe we should just free?
|
// We couldn't find the target. Maybe we should just free?
|
||||||
|
@ -849,6 +863,7 @@ chan_id_send(rust_task *task, type_desc *t, rust_task_id target_task_id,
|
||||||
if(port) {
|
if(port) {
|
||||||
port->remote_chan->send(sptr);
|
port->remote_chan->send(sptr);
|
||||||
}
|
}
|
||||||
|
target_task->deref();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ rust_kernel::get_task_by_id(rust_task_id id) {
|
||||||
rust_task *task = NULL;
|
rust_task *task = NULL;
|
||||||
// get leaves task unchanged if not found.
|
// get leaves task unchanged if not found.
|
||||||
task_table.get(id, &task);
|
task_table.get(id, &task);
|
||||||
|
if(task) task->ref();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,9 @@ upcall_clone_chan(rust_task *task, rust_task_id tid,
|
||||||
// FIXME: This should be removed.
|
// FIXME: This should be removed.
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
rust_task *target = task->kernel->get_task_by_id(tid);
|
rust_task *target = task->kernel->get_task_by_id(tid);
|
||||||
return chan->clone(target);
|
rust_chan *c = chan->clone(target);
|
||||||
|
target->deref();
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL rust_task *
|
extern "C" CDECL rust_task *
|
||||||
|
@ -197,6 +199,7 @@ upcall_kill(rust_task *task, rust_task_id tid) {
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
rust_task *target = task->kernel->get_task_by_id(tid);
|
rust_task *target = task->kernel->get_task_by_id(tid);
|
||||||
target->kill();
|
target->kill();
|
||||||
|
target->deref();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,7 +318,9 @@ extern "C" CDECL rust_str *
|
||||||
upcall_dup_str(rust_task *task, rust_task_id tid, rust_str *str) {
|
upcall_dup_str(rust_task *task, rust_task_id tid, rust_str *str) {
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
rust_task *target = task->kernel->get_task_by_id(tid);
|
rust_task *target = task->kernel->get_task_by_id(tid);
|
||||||
return make_str(target, (char const *)str->data, str->fill);
|
rust_str *s = make_str(target, (char const *)str->data, str->fill);
|
||||||
|
target->deref();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL rust_vec *
|
extern "C" CDECL rust_vec *
|
||||||
|
@ -478,27 +483,25 @@ upcall_new_task(rust_task *spawner, rust_vec *name) {
|
||||||
LOG_UPCALL_ENTRY(spawner);
|
LOG_UPCALL_ENTRY(spawner);
|
||||||
rust_task_id tid =
|
rust_task_id tid =
|
||||||
spawner->kernel->create_task(spawner, (const char *)name->data);
|
spawner->kernel->create_task(spawner, (const char *)name->data);
|
||||||
rust_task *task = spawner->kernel->get_task_by_id(tid);
|
// let the kernel bump the ref count.
|
||||||
task->ref();
|
spawner->kernel->get_task_by_id(tid);
|
||||||
|
// no deref because we're letting the caller take ownership.
|
||||||
return tid;
|
return tid;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
upcall_take_task(rust_task *task, rust_task_id tid) {
|
upcall_take_task(rust_task *task, rust_task_id tid) {
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
rust_task *target = task->kernel->get_task_by_id(tid);
|
// get_task_by_id increments the refcount.
|
||||||
if(target) {
|
task->kernel->get_task_by_id(tid);
|
||||||
target->ref();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL void
|
||||||
|
drop_task(rust_task *task, rust_task_id tid);
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
upcall_drop_task(rust_task *task, rust_task_id tid) {
|
upcall_drop_task(rust_task *task, rust_task_id tid) {
|
||||||
LOG_UPCALL_ENTRY(task);
|
LOG_UPCALL_ENTRY(task);
|
||||||
rust_task *target = task->kernel->get_task_by_id(tid);
|
drop_task(task, tid);
|
||||||
if(target) {
|
|
||||||
target->deref();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
|
@ -544,6 +547,7 @@ upcall_start_task(rust_task *spawner,
|
||||||
memcpy((void*)task->rust_sp, (void*)args, args_sz);
|
memcpy((void*)task->rust_sp, (void*)args, args_sz);
|
||||||
|
|
||||||
task->start(spawnee_fn, child_arg);
|
task->start(spawnee_fn, child_arg);
|
||||||
|
task->deref();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ debug_tydesc
|
||||||
do_gc
|
do_gc
|
||||||
drop_chan
|
drop_chan
|
||||||
drop_port
|
drop_port
|
||||||
|
drop_task
|
||||||
get_port_id
|
get_port_id
|
||||||
get_task_context
|
get_task_context
|
||||||
get_task_id
|
get_task_id
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue