about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-27 12:29:38 -0700
committerEric Holk <eholk@mozilla.com>2011-07-28 10:47:28 -0700
commita5fe66e7065c0e91064f3a818ea901ecfb499b70 (patch)
tree52d5186c3ddbc4af42c3db3218cbaac909a75e6c
parent5302cde188bba80dd38c58eaafa792d621b0818c (diff)
downloadrust-a5fe66e7065c0e91064f3a818ea901ecfb499b70.tar.gz
rust-a5fe66e7065c0e91064f3a818ea901ecfb499b70.zip
Adding upcalls to to ref() and deref() tasks. This is the first step towards atomic reference counting of tasks.
-rw-r--r--src/comp/back/upcall.rs4
-rw-r--r--src/comp/middle/trans.rs15
-rw-r--r--src/comp/middle/ty.rs5
-rw-r--r--src/rt/rust_upcall.cpp17
-rw-r--r--src/rt/rustrt.def.in2
-rw-r--r--src/rt/sync/lock_and_signal.cpp2
6 files changed, 42 insertions, 3 deletions
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