Skip to content

Commit 1b28129

Browse files
committed
---
yaml --- r: 13558 b: refs/heads/master c: be664dd h: refs/heads/master v: v3
1 parent 4aa9b8c commit 1b28129

File tree

9 files changed

+75
-17
lines changed

9 files changed

+75
-17
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: dc718d97a64e8177690cd21a49eee9c28220df2d
2+
refs/heads/master: be664ddd2917e13c1c5f05a49476f8b67be85140
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/libstd/arc.rs renamed to trunk/src/libcore/arc.rs

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
share immutable data between tasks."]
33

44
import comm::{port, chan, methods};
5+
import sys::methods;
56

67
export arc, get, clone, shared_arc, get_arc;
78

9+
export exclusive, methods;
10+
811
#[abi = "cdecl"]
912
native mod rustrt {
1013
#[rust_stack]
@@ -16,12 +19,12 @@ native mod rustrt {
1619
-> libc::intptr_t;
1720
}
1821

19-
type arc_data<T: const> = {
22+
type arc_data<T> = {
2023
mut count: libc::intptr_t,
2124
data: T
2225
};
2326

24-
resource arc_destruct<T: const>(data: *libc::c_void) {
27+
resource arc_destruct<T>(data: *libc::c_void) {
2528
unsafe {
2629
let data: ~arc_data<T> = unsafe::reinterpret_cast(data);
2730
let new_count = rustrt::rust_atomic_decrement(&mut data.count);
@@ -71,6 +74,43 @@ fn clone<T: const>(rc: &arc<T>) -> arc<T> {
7174
arc_destruct(**rc)
7275
}
7376

77+
// An arc over mutable data that is protected by a lock.
78+
type ex_data<T> = {lock: sys::lock_and_signal, data: T};
79+
type exclusive<T> = arc_destruct<ex_data<T>>;
80+
81+
fn exclusive<T>(-data: T) -> exclusive<T> {
82+
let data = ~{mut count: 1, data: {lock: sys::create_lock(),
83+
data: data}};
84+
unsafe {
85+
let ptr = unsafe::reinterpret_cast(data);
86+
unsafe::forget(data);
87+
arc_destruct(ptr)
88+
}
89+
}
90+
91+
impl methods<T> for exclusive<T> {
92+
fn clone() -> exclusive<T> {
93+
unsafe {
94+
// this makes me nervous...
95+
let ptr: ~arc_data<ex_data<T>> = unsafe::reinterpret_cast(*self);
96+
rustrt::rust_atomic_increment(&mut ptr.count);
97+
unsafe::forget(ptr);
98+
}
99+
arc_destruct(*self)
100+
}
101+
102+
fn with<U>(f: fn(sys::condition, x: &T) -> U) -> U {
103+
unsafe {
104+
let ptr: ~arc_data<ex_data<T>> = unsafe::reinterpret_cast(*self);
105+
let rec: &ex_data<T> = &(*ptr).data;
106+
unsafe::forget(ptr);
107+
rec.lock.lock_cond() {|c|
108+
f(c, &rec.data)
109+
}
110+
}
111+
}
112+
}
113+
74114
// Convenience code for sharing arcs between tasks
75115

76116
type get_chan<T: const send> = chan<chan<arc<T>>>;
@@ -115,6 +155,7 @@ fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
115155
#[cfg(test)]
116156
mod tests {
117157
import comm::*;
158+
import future::future;
118159

119160
#[test]
120161
fn manually_share_arc() {
@@ -160,4 +201,31 @@ mod tests {
160201

161202
assert p.recv() == ();
162203
}
204+
205+
#[test]
206+
fn exclusive_arc() {
207+
let mut futures = [];
208+
209+
let num_tasks = 10u;
210+
let count = 1000u;
211+
212+
let total = exclusive(~mut 0u);
213+
214+
for uint::range(0u, num_tasks) {|_i|
215+
let total = total.clone();
216+
futures += [future::spawn({||
217+
for uint::range(0u, count) {|_i|
218+
total.with {|_cond, count|
219+
**count += 1u;
220+
}
221+
}
222+
})];
223+
};
224+
225+
for futures.each {|f| f.get() };
226+
227+
total.with {|_cond, total|
228+
assert **total == num_tasks * count
229+
};
230+
}
163231
}

trunk/src/libcore/core.rc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export float, f32, f64;
3939
export box, char, str, ptr, vec, bool;
4040
export either, option, result, iter;
4141
export libc, os, io, run, rand, sys, unsafe, logging;
42-
export comm, task, future;
42+
export arc, comm, task, future;
4343
export extfmt;
4444
export tuple;
4545
export to_str;
@@ -175,6 +175,7 @@ mod dvec_iter {
175175
}
176176

177177
// Concurrency
178+
mod arc;
178179
mod comm;
179180
mod task;
180181
mod future;

trunk/src/libcore/sys.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export min_align_of;
77
export pref_align_of;
88
export refcount;
99
export log_str;
10-
export lock_and_signal, condition, methods;
10+
export create_lock, lock_and_signal, condition, methods;
1111

1212
enum type_desc = {
1313
first_param: **libc::c_int,
@@ -126,8 +126,6 @@ impl methods for condition {
126126

127127
#[cfg(test)]
128128
mod tests {
129-
use std;
130-
import std::arc;
131129

132130
#[test]
133131
fn size_of_basic() {

trunk/src/libstd/std.rc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export net, net_tcp;
1919
export uv, uv_ll, uv_iotask, uv_global_loop;
2020
export c_vec, util, timer;
2121
export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap;
22-
export rope, arena, arc, par;
22+
export rope, arena, par;
2323
export ebml, dbg, getopts, json, rand, sha1, term, time, prettyprint;
2424
export test, tempfile, serialization;
2525
export cmp;
@@ -69,7 +69,6 @@ mod term;
6969
mod time;
7070
mod prettyprint;
7171
mod arena;
72-
mod arc;
7372
mod par;
7473
mod cmp;
7574

trunk/src/test/bench/graph500-bfs.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import std::map;
1010
import std::map::hashmap;
1111
import std::deque;
1212
import std::deque::t;
13-
import std::arc;
1413
import std::par;
1514
import io::writer_util;
1615
import comm::*;

trunk/src/test/compile-fail/no-capture-arc.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// error-pattern: copying a noncopyable value
22

3-
use std;
4-
import std::arc;
53
import comm::*;
64

75
fn main() {

trunk/src/test/compile-fail/no-reuse-move-arc.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std;
2-
import std::arc;
31
import comm::*;
42

53
fn main() {

trunk/src/test/run-fail/issue-2444.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
// error-pattern:explicit failure
22

3-
use std;
4-
import std::arc;
5-
63
enum e<T: const> { e(arc::arc<T>) }
74

85
fn foo() -> e<int> {fail;}

0 commit comments

Comments
 (0)