Skip to content

Commit 331e3a8

Browse files
author
Eric Holk
committed
---
yaml --- r: 4453 b: refs/heads/master c: b62e80c h: refs/heads/master i: 4451: cbe9b8b v: v3
1 parent 7b54c0d commit 331e3a8

File tree

13 files changed

+62
-39
lines changed

13 files changed

+62
-39
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 200bbcf91b4eb190cff227127cc60a333f9c33a2
2+
refs/heads/master: b62e80c1f022131da963da84ef6768f300c2c5c3

trunk/src/comp/back/upcall.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ type upcalls =
3636
del_port: ValueRef,
3737
new_chan: ValueRef,
3838
flush_chan: ValueRef,
39+
drop_chan: ValueRef,
40+
take_chan: ValueRef,
3941
del_chan: ValueRef,
4042
clone_chan: ValueRef,
4143
chan_target_task: ValueRef,
@@ -94,6 +96,8 @@ fn declare_upcalls(tn: type_names, tydesc_type: TypeRef,
9496
new_chan:
9597
d("new_chan", ~[T_opaque_port_ptr()], T_opaque_chan_ptr()),
9698
flush_chan: dv("flush_chan", ~[T_opaque_chan_ptr()]),
99+
drop_chan: dv("drop_chan", ~[T_opaque_chan_ptr()]),
100+
take_chan: dv("take_chan", ~[T_opaque_chan_ptr()]),
97101
del_chan: dv("del_chan", ~[T_opaque_chan_ptr()]),
98102
clone_chan:
99103
d("clone_chan", ~[taskptr_type, T_opaque_chan_ptr()],

trunk/src/comp/middle/trans.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,12 @@ fn make_copy_glue(cx: &@block_ctxt, v: ValueRef, t: &ty::t) {
12371237
cx.build.Call(bcx_ccx(cx).upcalls.take_task,
12381238
~[cx.fcx.lltaskptr, task_ptr]);
12391239
bcx = cx;
1240+
} else if ty::type_is_chan(bcx_tcx(cx), t) {
1241+
let ptr = cx.build.Load(v);
1242+
ptr = cx.build.PointerCast(ptr, T_opaque_chan_ptr());
1243+
cx.build.Call(bcx_ccx(cx).upcalls.take_chan,
1244+
~[cx.fcx.lltaskptr, ptr]);
1245+
bcx = cx;
12401246
} else if ty::type_is_boxed(bcx_tcx(cx), t) {
12411247
bcx = incr_refcnt_of_boxed(cx, cx.build.Load(v)).bcx;
12421248
} else if (ty::type_is_structural(bcx_tcx(cx), t)) {
@@ -1395,7 +1401,13 @@ fn make_drop_glue(cx: &@block_ctxt, v0: ValueRef, t: &ty::t) {
13951401
}
13961402
ty::ty_box(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
13971403
ty::ty_port(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
1398-
ty::ty_chan(_) { decr_refcnt_maybe_free(cx, v0, v0, t) }
1404+
ty::ty_chan(_) {
1405+
let ptr = cx.build.Load(v0);
1406+
ptr = cx.build.PointerCast(ptr, T_opaque_chan_ptr());
1407+
{bcx: cx,
1408+
val: cx.build.Call(bcx_ccx(cx).upcalls.drop_chan,
1409+
~[cx.fcx.lltaskptr, ptr])}
1410+
}
13991411
ty::ty_task. {
14001412
let task_ptr = cx.build.Load(v0);
14011413
{bcx: cx,

trunk/src/rt/memory_region.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// NB: please do not commit code with this uncommented. It's
55
// hugely expensive and should only be used as a last resort.
66
//
7-
//#define TRACK_ALLOCATIONS
7+
// #define TRACK_ALLOCATIONS
88

99
#define MAGIC 0xbadc0ffe
1010

trunk/src/rt/rust_builtin.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,9 +904,14 @@ void del_chan(rust_task *task, rust_chan *chan) {
904904
chan->destroy();
905905
}
906906

907+
extern "C" CDECL
908+
void take_chan(rust_task *task, rust_chan *chan) {
909+
chan->ref();
910+
}
911+
907912
extern "C" CDECL
908913
void drop_chan(rust_task *task, rust_chan *chan) {
909-
chan->ref_count--;
914+
chan->deref();
910915
}
911916

912917
extern "C" CDECL

trunk/src/rt/rust_chan.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ rust_chan::~rust_chan() {
2222
KLOG(kernel, comm, "del rust_chan(task=0x%" PRIxPTR ")",
2323
(uintptr_t) this);
2424

25+
this->destroy();
26+
2527
A(kernel, is_associated() == false,
2628
"Channel must be disassociated before being freed.");
2729
}
@@ -35,7 +37,7 @@ void rust_chan::associate(rust_port *port) {
3537
KLOG(kernel, task,
3638
"associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR,
3739
this, port);
38-
++this->ref_count;
40+
this->ref();
3941
this->task = port->task;
4042
this->task->ref();
4143
this->port->chans.push(this);
@@ -57,13 +59,14 @@ void rust_chan::disassociate() {
5759
KLOG(kernel, task,
5860
"disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR,
5961
this, port);
60-
--this->ref_count;
6162
task->deref();
6263
this->task = NULL;
6364
port->chans.swap_delete(this);
6465

6566
// Delete reference to the port.
6667
port = NULL;
68+
69+
this->deref();
6770
}
6871

6972
/**
@@ -101,9 +104,6 @@ rust_chan *rust_chan::clone(rust_task *target) {
101104
* appear to be live, causing modify-after-free errors.
102105
*/
103106
void rust_chan::destroy() {
104-
A(kernel, ref_count == 0,
105-
"Channel's ref count should be zero.");
106-
107107
if (is_associated()) {
108108
// We're trying to delete a channel that another task may be
109109
// reading from. We have two options:
@@ -121,7 +121,6 @@ void rust_chan::destroy() {
121121
scoped_lock with(port->lock);
122122
disassociate();
123123
}
124-
delete this;
125124
}
126125

127126
//

trunk/src/rt/rust_chan.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
class rust_chan : public kernel_owned<rust_chan>,
55
public rust_cond {
6+
~rust_chan();
7+
68
public:
7-
RUST_REFCOUNTED_WITH_DTOR(rust_chan, destroy())
9+
RUST_ATOMIC_REFCOUNT();
810
rust_chan(rust_kernel *kernel, rust_port *port,
911
size_t unit_sz);
1012

11-
~rust_chan();
12-
1313
rust_kernel *kernel;
1414
rust_task *task;
1515
rust_port *port;

trunk/src/rt/rust_internal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ static size_t const BUF_BYTES = 2048;
108108
void ref() { ++ref_count; } \
109109
void deref() { if (--ref_count == 0) { dtor; } }
110110

111+
#define RUST_ATOMIC_REFCOUNT() \
112+
private: \
113+
intptr_t ref_count; \
114+
public: \
115+
void ref() { sync::increment(ref_count); } \
116+
void deref() { if(0 == sync::decrement(ref_count)) { delete this; } }
117+
111118
template <typename T> struct rc_base {
112119
RUST_REFCOUNTED(T)
113120

trunk/src/rt/rust_port.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ rust_port::rust_port(rust_task *task, size_t unit_sz)
88
LOG(task, comm,
99
"new rust_port(task=0x%" PRIxPTR ", unit_sz=%d) -> port=0x%"
1010
PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this);
11-
12-
// Allocate a remote channel, for remote channel data.
13-
remote_channel = new (kernel, "remote chan")
14-
rust_chan(kernel, this, unit_sz);
1511
}
1612

1713
rust_port::~rust_port() {
@@ -22,15 +18,7 @@ rust_port::~rust_port() {
2218
scoped_lock with(lock);
2319
rust_chan *chan = chans.peek();
2420
chan->disassociate();
25-
26-
if (chan->ref_count == 0) {
27-
LOG(task, comm,
28-
"chan: 0x%" PRIxPTR " is dormant, freeing", chan);
29-
delete chan;
30-
}
3121
}
32-
33-
delete remote_channel;
3422
}
3523

3624
bool rust_port::receive(void *dptr) {
@@ -52,10 +40,9 @@ void rust_port::log_state() {
5240
for (uint32_t i = 0; i < chans.length(); i++) {
5341
rust_chan *chan = chans[i];
5442
LOG(task, comm,
55-
"\tchan: 0x%" PRIxPTR ", size: %d, remote: %s",
43+
"\tchan: 0x%" PRIxPTR ", size: %d",
5644
chan,
57-
chan->buffer.size(),
58-
chan == remote_channel ? "yes" : "no");
45+
chan->buffer.size());
5946
}
6047
}
6148

trunk/src/rt/rust_port.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ class rust_port : public kernel_owned<rust_port>, public rust_cond {
1212
ptr_vec<rust_token> writers;
1313
ptr_vec<rust_chan> chans;
1414

15-
// Data sent to this port from remote tasks is buffered in this channel.
16-
rust_chan *remote_channel;
17-
1815
lock_and_signal lock;
1916

2017
rust_port(rust_task *task, size_t unit_sz);

trunk/src/rt/rust_task.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,7 @@ struct gc_alloc {
3838
struct
3939
rust_task : public kernel_owned<rust_task>, rust_cond
4040
{
41-
// This block could be pulled out into something like a
42-
// RUST_ATOMIC_REFCOUNTED macro.
43-
private:
44-
intptr_t ref_count;
45-
public:
46-
void ref() { sync::increment(ref_count); }
47-
void deref() { if(0 == sync::decrement(ref_count)) { delete this; } }
48-
41+
RUST_ATOMIC_REFCOUNT();
4942

5043
// Fields known to the compiler.
5144
stk_seg *stk;

trunk/src/rt/rust_upcall.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,22 @@ upcall_drop_task(rust_task *task, rust_task *target) {
508508
}
509509
}
510510

511+
extern "C" CDECL void
512+
upcall_take_chan(rust_task *task, rust_chan *target) {
513+
LOG_UPCALL_ENTRY(task);
514+
if(target) {
515+
target->ref();
516+
}
517+
}
518+
519+
extern "C" CDECL void
520+
upcall_drop_chan(rust_task *task, rust_chan *target) {
521+
LOG_UPCALL_ENTRY(task);
522+
if(target) {
523+
target->deref();
524+
}
525+
}
526+
511527
extern "C" CDECL rust_task *
512528
upcall_start_task(rust_task *spawner,
513529
rust_task *task,

trunk/src/rt/rustrt.def.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ str_from_vec
6969
str_push_byte
7070
str_slice
7171
str_vec
72+
take_chan
7273
task_sleep
7374
task_yield
7475
task_join
@@ -78,6 +79,7 @@ upcall_chan_target_task
7879
upcall_clone_chan
7980
upcall_del_chan
8081
upcall_del_port
82+
upcall_drop_chan
8183
upcall_drop_task
8284
upcall_dup_str
8385
upcall_exit
@@ -108,6 +110,7 @@ upcall_shared_free
108110
upcall_sleep
109111
upcall_start_task
110112
upcall_take_task
113+
upcall_take_chan
111114
upcall_trace_str
112115
upcall_trace_word
113116
upcall_vec_append

0 commit comments

Comments
 (0)