diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index b12ceba8f0d..aa50b75e8b7 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -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), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 0b0b31b2064..28308b853ea 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -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)]); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index ccd11cad130..fb8f18993b7 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -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; } diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 3415b6b62ae..103aa49a6e9 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -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, diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 8326cabea88..d6c218d936d 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -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 diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp index f4c3778837d..67f6b107b3a 100644 --- a/src/rt/sync/lock_and_signal.cpp +++ b/src/rt/sync/lock_and_signal.cpp @@ -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