Skip to content

Commit 4c1457d

Browse files
committed
---
yaml --- r: 13004 b: refs/heads/master c: 6fa1a08 h: refs/heads/master v: v3
1 parent 630806c commit 4c1457d

File tree

6 files changed

+102
-2
lines changed

6 files changed

+102
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 9773a22119bf416a1c53d0ee30f6a127c7e274e1
2+
refs/heads/master: 6fa1a084f7714023c4594ec7a857359824dc3253
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/arc.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#[doc = "An atomically reference counted wrapper that can be used
2+
hare immutable data between tasks."]
3+
4+
export arc, get, clone;
5+
6+
#[abi = "cdecl"]
7+
native mod rustrt {
8+
#[rust_stack]
9+
fn rust_atomic_increment(p: *mut libc::intptr_t)
10+
-> libc::intptr_t;
11+
12+
#[rust_stack]
13+
fn rust_atomic_decrement(p: *mut libc::intptr_t)
14+
-> libc::intptr_t;
15+
}
16+
17+
type arc_data<T> = {
18+
mut count: libc::intptr_t,
19+
data: T
20+
};
21+
22+
resource arc_destruct<T>(data: *arc_data<T>) {
23+
unsafe {
24+
let ptr = ptr::mut_addr_of((*data).count);
25+
26+
let new_count = rustrt::rust_atomic_decrement(ptr);
27+
assert new_count >= 0;
28+
if new_count == 0 {
29+
let _ptr : ~arc_data<T> = unsafe::reinterpret_cast(data);
30+
// drop glue takes over.
31+
}
32+
}
33+
}
34+
35+
type arc<T> = arc_destruct<T>;
36+
37+
fn arc<T>(-data: T) -> arc<T> {
38+
let data = ~{mut count: 1, data: data};
39+
unsafe {
40+
let ptr = unsafe::reinterpret_cast(data);
41+
unsafe::forget(data);
42+
arc_destruct(ptr)
43+
}
44+
}
45+
46+
fn get<T>(rc: &a.arc<T>) -> &a.T {
47+
unsafe {
48+
&(***rc).data
49+
}
50+
}
51+
52+
fn clone<T>(rc: &arc<T>) -> arc<T> {
53+
let data = **rc;
54+
unsafe {
55+
rustrt::rust_atomic_increment(
56+
ptr::mut_addr_of((*data).count));
57+
}
58+
arc_destruct(**rc)
59+
}

trunk/src/libstd/std.rc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export net, net_tcp;
1717
export uv, uv_ll, uv_hl, uv_global_loop;
1818
export c_vec, util, timer;
1919
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap;
20-
export rope, arena;
20+
export rope, arena, arc;
2121
export ebml, dbg, getopts, json, rand, sha1, term, time, prettyprint;
2222
export test, tempfile, serialization;
2323

@@ -66,6 +66,7 @@ mod term;
6666
mod time;
6767
mod prettyprint;
6868
mod arena;
69+
mod arc;
6970

7071
#[cfg(unicode)]
7172
mod unicode;

trunk/src/rt/rust_builtin.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,16 @@ rust_compare_and_swap_ptr(intptr_t *address,
816816
return sync::compare_and_swap(address, oldval, newval);
817817
}
818818

819+
extern "C" CDECL intptr_t
820+
rust_atomic_increment(intptr_t *address) {
821+
return sync::increment(address);
822+
}
823+
824+
extern "C" CDECL intptr_t
825+
rust_atomic_decrement(intptr_t *address) {
826+
return sync::decrement(address);
827+
}
828+
819829
extern "C" CDECL void
820830
rust_task_weaken(rust_port_id chan) {
821831
rust_task *task = rust_get_current_task();

trunk/src/rt/rustrt.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ rust_dbg_lock_signal
154154
rust_dbg_call
155155
rust_osmain_sched_id
156156
rust_compare_and_swap_ptr
157+
rust_atomic_increment
158+
rust_atomic_decrement
157159
rust_global_env_chan_ptr
158160
rust_port_take
159161
rust_port_drop

trunk/src/test/run-pass/share-arc.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use std;
2+
import std::arc;
3+
import comm::*;
4+
5+
fn main() {
6+
let v = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
7+
let arc_v = arc::arc(v);
8+
9+
let p = port();
10+
let c = chan(p);
11+
12+
task::spawn() {||
13+
let p = port();
14+
c.send(chan(p));
15+
16+
let arc_v = p.recv();
17+
18+
let v = *arc::get::<[int]>(&arc_v);
19+
assert v[3] == 4;
20+
};
21+
22+
let c = p.recv();
23+
c.send(arc::clone(&arc_v));
24+
25+
assert (*arc::get(&arc_v))[2] == 3;
26+
27+
log(info, arc_v);
28+
}

0 commit comments

Comments
 (0)