Adding upcalls to to ref() and deref() tasks. This is the first step towards atomic reference counting of tasks.

This commit is contained in:
Eric Holk 2011-07-27 12:29:38 -07:00
parent 5302cde188
commit a5fe66e706
6 changed files with 42 additions and 3 deletions

View File

@ -57,6 +57,8 @@ type upcalls =
vec_append: ValueRef,
get_type_desc: ValueRef,
new_task: ValueRef,
take_task: ValueRef,
drop_task: ValueRef,
start_task: ValueRef,
ivec_resize: ValueRef,
ivec_spill: ValueRef,
@ -129,6 +131,8 @@ fn declare_upcalls(tn: type_names, tydesc_type: TypeRef,
~[T_ptr(T_nil()), T_size_t(), T_size_t(), T_size_t(),
T_ptr(T_ptr(tydesc_type))], T_ptr(tydesc_type)),
new_task: d("new_task", ~[T_ptr(T_str())], taskptr_type),
take_task: dv("take_task", ~[taskptr_type]),
drop_task: dv("drop_task", ~[taskptr_type]),
start_task:
d("start_task", ~[taskptr_type, T_int(), T_int(), T_size_t()],
taskptr_type),

View File

@ -1221,7 +1221,13 @@ fn make_copy_glue(cx: &@block_ctxt, v: ValueRef, t: &ty::t) {
// NB: v is an *alias* of type t here, not a direct value.
let bcx;
if ty::type_is_boxed(bcx_tcx(cx), t) {
if ty::type_is_task(bcx_tcx(cx), t) {
let task_ptr = cx.build.Load(v);
cx.build.Call(bcx_ccx(cx).upcalls.take_task,
~[cx.fcx.lltaskptr, task_ptr]);
bcx = cx;
} else if ty::type_is_boxed(bcx_tcx(cx), t) {
bcx = incr_refcnt_of_boxed(cx, cx.build.Load(v)).bcx;
} else if (ty::type_is_structural(bcx_tcx(cx), t)) {
bcx = duplicate_heap_parts_if_necessary(cx, v, t).bcx;
@ -1381,7 +1387,12 @@ fn make_drop_glue(cx: &@block_ctxt, v0: ValueRef, t: &ty::t) {
ty::ty_box(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
ty::ty_port(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
ty::ty_chan(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
ty::ty_task. { decr_refcnt_maybe_free(cx, v0, v0, t) }
ty::ty_task. {
let task_ptr = cx.build.Load(v0);
{bcx: cx,
val: cx.build.Call(bcx_ccx(cx).upcalls.drop_task,
~[cx.fcx.lltaskptr, task_ptr])}
}
ty::ty_obj(_) {
let box_cell =
cx.build.GEP(v0, ~[C_int(0), C_int(abi::obj_field_box)]);

View File

@ -162,6 +162,7 @@ export type_is_bot;
export type_is_box;
export type_is_boxed;
export type_is_chan;
export type_is_task;
export type_is_fp;
export type_is_integral;
export type_is_native;
@ -842,6 +843,10 @@ fn type_is_chan(cx: &ctxt, ty: &t) -> bool {
alt struct(cx, ty) { ty_chan(_) { ret true; } _ { ret false; } }
}
fn type_is_task(cx: &ctxt, ty: &t) -> bool {
alt struct(cx, ty) { ty_task. { ret true; } _ { ret false; } }
}
fn type_is_structural(cx: &ctxt, ty: &t) -> bool {
alt struct(cx, ty) {
ty_rec(_) { ret true; }

View File

@ -547,6 +547,23 @@ upcall_new_task(rust_task *spawner, rust_vec *name) {
return task;
}
extern "C" CDECL void
upcall_take_task(rust_task *task, rust_task *target) {
LOG_UPCALL_ENTRY(task);
if(target) {
target->ref();
}
}
extern "C" CDECL void
upcall_drop_task(rust_task *task, rust_task *target) {
LOG_UPCALL_ENTRY(task);
if(target) {
//target->deref();
--target->ref_count;
}
}
extern "C" CDECL rust_task *
upcall_start_task(rust_task *spawner,
rust_task *task,

View File

@ -59,6 +59,7 @@ upcall_chan_target_task
upcall_clone_chan
upcall_del_chan
upcall_del_port
upcall_drop_task
upcall_dup_str
upcall_exit
upcall_fail
@ -87,6 +88,7 @@ upcall_shared_malloc
upcall_shared_free
upcall_sleep
upcall_start_task
upcall_take_task
upcall_trace_str
upcall_trace_word
upcall_vec_append

View File

@ -10,7 +10,7 @@
#include "lock_and_signal.h"
#if defined(__WIN32__)
lock_and_signal::lock_and_signal()
lock_and_signal::lock_and_signal()
: alive(true)
{
// FIXME: In order to match the behavior of pthread_cond_broadcast on