Skip to content

Commit 39b1607

Browse files
author
Eric Holk
committed
Port ID-based channels.
1 parent 04af99e commit 39b1607

File tree

9 files changed

+96
-7
lines changed

9 files changed

+96
-7
lines changed

src/lib/comm.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import sys;
22
import ptr;
33
import unsafe;
4+
import task;
5+
import task::task_id;
46

57
export _chan;
68
export _port;
79

810
export mk_port;
911
export chan_from_unsafe_ptr;
12+
export send;
1013

1114
native "rust" mod rustrt {
1215
type void;
@@ -17,16 +20,28 @@ native "rust" mod rustrt {
1720
fn take_chan(ch : *rust_chan);
1821
fn drop_chan(ch : *rust_chan);
1922
fn chan_send(ch: *rust_chan, v : *void);
23+
// FIXME: data should be -T, not &T, but this doesn't seem to be
24+
// supported yet.
25+
fn chan_id_send[~T](target_task : task_id, target_port : port_id,
26+
data : &T);
2027

2128
fn new_port(unit_sz : uint) -> *rust_port;
2229
fn del_port(po : *rust_port);
2330
fn drop_port(po : *rust_port);
31+
fn get_port_id(po : *rust_port) -> port_id;
2432
}
2533

2634
native "rust-intrinsic" mod rusti {
27-
fn recv[T](port : *rustrt::rust_port) -> T;
35+
fn recv[~T](port : *rustrt::rust_port) -> T;
2836
}
2937

38+
type port_id = int;
39+
40+
type chan_t[~T] = {
41+
task : task_id,
42+
port : port_id
43+
};
44+
3045
resource chan_ptr(ch: *rustrt::rust_chan) {
3146
rustrt::drop_chan(ch);
3247
}
@@ -36,7 +51,7 @@ resource port_ptr(po: *rustrt::rust_port) {
3651
rustrt::del_port(po);
3752
}
3853

39-
obj _chan[T](raw_chan : @chan_ptr) {
54+
obj _chan[~T](raw_chan : @chan_ptr) {
4055
fn send(v : &T) {
4156
rustrt::chan_send(**raw_chan,
4257
unsafe::reinterpret_cast(ptr::addr_of(v)));
@@ -49,20 +64,33 @@ obj _chan[T](raw_chan : @chan_ptr) {
4964
}
5065
}
5166

52-
fn chan_from_unsafe_ptr[T](ch : *u8) -> _chan[T] {
67+
fn chan_from_unsafe_ptr[~T](ch : *u8) -> _chan[T] {
5368
_chan(@chan_ptr(unsafe::reinterpret_cast(ch)))
5469
}
5570

56-
obj _port[T](raw_port : @port_ptr) {
71+
obj _port[~T](raw_port : @port_ptr) {
5772
fn mk_chan() -> _chan[T] {
5873
_chan(@chan_ptr(rustrt::new_chan(**raw_port)))
5974
}
6075

76+
// FIXME: rename this to chan once chan is not a keyword.
77+
fn mk_chan2() -> chan_t[T] {
78+
{
79+
task: task::get_task_id(),
80+
port: rustrt::get_port_id(**raw_port)
81+
}
82+
}
83+
6184
fn recv() -> T {
6285
ret rusti::recv(**raw_port)
6386
}
6487
}
6588

66-
fn mk_port[T]() -> _port[T] {
89+
fn mk_port[~T]() -> _port[T] {
6790
_port(@port_ptr(rustrt::new_port(sys::size_of[T]())))
6891
}
92+
93+
// FIXME: make data move-mode once the snapshot is updated.
94+
fn send[~T](ch : chan_t[T], data : &T) {
95+
rustrt::chan_id_send(ch.task, ch.port, data);
96+
}

src/lib/task.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,20 @@ native "rust" mod rustrt {
55
fn unsupervise();
66
fn pin_task();
77
fn unpin_task();
8+
fn get_task_id() -> task_id;
89
fn clone_chan(c: *rust_chan) -> *rust_chan;
910

1011
type rust_chan;
1112

1213
fn set_min_stack(stack_size: uint);
1314
}
1415

16+
type task_id = int;
17+
18+
fn get_task_id() -> task_id {
19+
rustrt::get_task_id()
20+
}
21+
1522
/**
1623
* Hints the scheduler to yield this task for a specified ammount of time.
1724
*
@@ -33,6 +40,7 @@ fn pin() { rustrt::pin_task(); }
3340

3441
fn unpin() { rustrt::unpin_task(); }
3542

43+
// FIXME: remove this
3644
fn clone_chan[T](c: chan[T]) -> chan[T] {
3745
let cloned = rustrt::clone_chan(unsafe::reinterpret_cast(c));
3846
ret unsafe::reinterpret_cast(cloned);

src/rt/rust_builtin.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,11 @@ unpin_task(rust_task *task) {
702702
task->unpin();
703703
}
704704

705+
extern "C" CDECL rust_task_id
706+
get_task_id(rust_task *task) {
707+
return task->id;
708+
}
709+
705710
extern "C" CDECL rust_chan *
706711
clone_chan(rust_task *task, rust_chan *chan) {
707712
return chan->clone(task);
@@ -738,6 +743,11 @@ del_port(rust_task *task, rust_port *port) {
738743
task->deref();
739744
}
740745

746+
extern "C" CDECL rust_port_id
747+
get_port_id(rust_task *task, rust_port *port) {
748+
return port->id;
749+
}
750+
741751
extern "C" CDECL rust_chan*
742752
new_chan(rust_task *task, rust_port *port) {
743753
rust_scheduler *sched = task->sched;
@@ -775,6 +785,19 @@ chan_send(rust_task *task, rust_chan *chan, void *sptr) {
775785
chan->send(sptr);
776786
}
777787

788+
extern "C" CDECL void
789+
chan_id_send(rust_task *task, type_desc *t, rust_task_id target_task_id,
790+
rust_port_id target_port_id, void *sptr) {
791+
// FIXME: make sure this is thread-safe
792+
rust_task *target_task = task->kernel->get_task_by_id(target_task_id);
793+
if(target_task) {
794+
rust_port *port = target_task->get_port_by_id(target_port_id);
795+
if(port) {
796+
port->remote_chan->send(sptr);
797+
}
798+
}
799+
}
800+
778801
extern "C" CDECL void
779802
port_recv(rust_task *task, uintptr_t *dptr, rust_port *port) {
780803
{

src/rt/rust_port.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#include "rust_internal.h"
22
#include "rust_port.h"
33

4+
extern "C" CDECL rust_chan*
5+
new_chan(rust_task *task, rust_port *port);
6+
47
rust_port::rust_port(rust_task *task, size_t unit_sz)
58
: ref_count(1), kernel(task->kernel), task(task),
69
unit_sz(unit_sz), writers(task), chans(task) {
@@ -10,6 +13,7 @@ rust_port::rust_port(rust_task *task, size_t unit_sz)
1013
PRIxPTR, (uintptr_t)task, unit_sz, (uintptr_t)this);
1114

1215
id = task->register_port(this);
16+
remote_chan = new_chan(task, this);
1317
}
1418

1519
rust_port::~rust_port() {
@@ -22,6 +26,9 @@ rust_port::~rust_port() {
2226
chan->disassociate();
2327
}
2428

29+
remote_chan->deref();
30+
remote_chan = NULL;
31+
2532
task->release_port(id);
2633
}
2734

src/rt/rust_port.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@ class rust_port : public kernel_owned<rust_port>, public rust_cond {
55
public:
66
RUST_REFCOUNTED(rust_port);
77

8-
private:
98
rust_port_id id;
109

11-
public:
1210
rust_kernel *kernel;
1311
rust_task *task;
12+
rust_chan *remote_chan;
1413
size_t unit_sz;
1514
ptr_vec<rust_token> writers;
1615
ptr_vec<rust_chan> chans;

src/rt/rustrt.def.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ aio_serve
99
aio_stop
1010
aio_writedata
1111
align_of
12+
chan_id_send
1213
chan_send
1314
check_claims
1415
clone_chan
@@ -25,6 +26,8 @@ debug_tydesc
2526
do_gc
2627
drop_chan
2728
drop_port
29+
get_port_id
30+
get_task_id
2831
get_time
2932
hack_allow_leaks
3033
ivec_copy_from_buf

src/test/run-pass/task-comm-10.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// FIXME: this test is xfailed until sending strings is legal again.
2+
3+
//xfail-stage0
4+
//xfail-stage1
5+
//xfail-stage2
6+
//xfail-stage3
7+
18
use std;
29
import std::task;
310
import std::comm;

src/test/run-pass/task-comm-16.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ fn test_vec() {
3232
}
3333

3434
fn test_str() {
35+
// FIXME: re-enable this once strings are unique and sendable
36+
/*
3537
let po = comm::mk_port();
3638
let ch = po.mk_chan();
3739
let s0: str = "test";
@@ -42,6 +44,7 @@ fn test_str() {
4244
assert (s1.(1) as u8 == 'e' as u8);
4345
assert (s1.(2) as u8 == 's' as u8);
4446
assert (s1.(3) as u8 == 't' as u8);
47+
*/
4548
}
4649

4750
fn test_tag() {

src/test/stdtest/comm.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,14 @@ fn send_recv() {
1717
log_err v;
1818
assert(42 == v);
1919
}
20+
21+
#[test]
22+
fn send_recv2() {
23+
let p = comm::mk_port[int]();
24+
let c = p.mk_chan2();
25+
26+
comm::send(c, 42);
27+
let v = p.recv();
28+
log_err v;
29+
assert(42 == v);
30+
}

0 commit comments

Comments
 (0)