Skip to content

Commit c97944f

Browse files
committed
core: add potential "simpler interface" to core::condition, also reduce TLS hits.
1 parent 6c4ad31 commit c97944f

File tree

1 file changed

+69
-18
lines changed

1 file changed

+69
-18
lines changed

src/libcore/condition.rs

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ struct Condition<T, U:Copy> {
66
}
77

88
struct Handler<T, U:Copy> {
9-
handle: RustClosure,
10-
prev: Option<@Handler<T, U>>
9+
handle: RustClosure
1110
}
1211

1312

@@ -16,34 +15,32 @@ struct ProtectBlock<T, U:Copy> {
1615
inner: RustClosure
1716
}
1817

19-
struct PopHandler<T, U:Copy> {
18+
struct Guard<T, U:Copy> {
2019
cond: &Condition<T,U>,
20+
prev: Option<@Handler<T, U>>,
2121
drop {
22-
unsafe {
23-
debug!("PopHandler: popping handler from TLS");
24-
match task::local_data::local_data_pop(self.cond.key) {
25-
None => (),
26-
Some(h) => {
27-
match h.prev {
28-
None => (),
29-
Some(p) =>
30-
task::local_data::local_data_set(self.cond.key, p)
31-
}
32-
}
22+
match self.prev {
23+
None => (),
24+
Some(p) =>
25+
unsafe {
26+
debug!("Guard: popping handler from TLS");
27+
task::local_data::local_data_set(self.cond.key, p)
3328
}
3429
}
3530
}
3631
}
3732

3833
struct HandleBlock<T, U:Copy> {
3934
pb: &ProtectBlock<T,U>,
35+
prev: Option<@Handler<T,U>>,
4036
handler: @Handler<T,U>,
4137
drop {
4238
unsafe {
4339
debug!("HandleBlock: pushing handler to TLS");
40+
let _g = Guard { cond: self.pb.cond,
41+
prev: self.prev };
4442
task::local_data::local_data_set(self.pb.cond.key,
4543
self.handler);
46-
let _pop = PopHandler { cond: self.pb.cond };
4744
// transmutation to avoid copying non-copyable, should
4845
// be fixable by tracking closure pointees in regionck.
4946
let f : &fn() = ::cast::transmute(self.pb.inner);
@@ -61,14 +58,27 @@ impl<T, U: Copy> ProtectBlock<T,U> {
6158
let p : *RustClosure = ::cast::transmute(&h);
6259
let prev = task::local_data::local_data_get(self.cond.key);
6360
HandleBlock { pb: self,
64-
handler: @Handler{handle: *p, prev: prev} }
61+
prev: prev,
62+
handler: @Handler{handle: *p} }
6563
}
6664
}
6765
}
6866

6967

7068
impl<T, U: Copy> Condition<T,U> {
7169

70+
fn guard(&self, h: &self/fn(&T) ->U) -> Guard/&self<T,U> {
71+
unsafe {
72+
let prev = task::local_data::local_data_get(self.key);
73+
let g = Guard { cond: self, prev: prev };
74+
debug!("Guard: pushing handler to TLS");
75+
let p : *RustClosure = ::cast::transmute(&h);
76+
let h = @Handler{handle: *p};
77+
task::local_data::local_data_set(self.key, h);
78+
move g
79+
}
80+
}
81+
7282
fn protect(&self, inner: &self/fn()) -> ProtectBlock/&self<T,U> {
7383
unsafe {
7484
// transmutation to avoid copying non-copyable, should
@@ -147,7 +157,7 @@ fn nested_test_inner() {
147157
trouble(1);
148158
};
149159

150-
do b.handle |_j:&int| {
160+
do b.handle |_j| {
151161
debug!("nested_test_inner: in handler");
152162
inner_trapped = true;
153163
0
@@ -170,11 +180,52 @@ fn nested_test_outer() {
170180
trouble(1);
171181
};
172182

173-
do b.handle |_j:&int| {
183+
do b.handle |_j| {
174184
debug!("nested_test_outer: in handler");
175185
outer_trapped = true;
176186
0
177187
};
178188

179189
assert outer_trapped;
180190
}
191+
192+
193+
#[cfg(test)]
194+
fn nested_guard_test_inner() {
195+
let sadness_condition : Condition<int,int> =
196+
Condition { key: sadness_key };
197+
198+
let mut inner_trapped = false;
199+
200+
let _g = do sadness_condition.guard |_j| {
201+
debug!("nested_guard_test_inner: in handler");
202+
inner_trapped = true;
203+
0
204+
};
205+
206+
debug!("nested_guard_test_inner: in protected block");
207+
trouble(1);
208+
209+
assert inner_trapped;
210+
}
211+
212+
#[test]
213+
fn nested_guard_test_outer() {
214+
215+
let sadness_condition : Condition<int,int> =
216+
Condition { key: sadness_key };
217+
218+
let mut outer_trapped = false;
219+
220+
let _g = do sadness_condition.guard |_j| {
221+
debug!("nested_guard_test_outer: in handler");
222+
outer_trapped = true;
223+
0
224+
};
225+
226+
debug!("nested_guard_test_outer: in protected block");
227+
nested_guard_test_inner();
228+
trouble(1);
229+
230+
assert outer_trapped;
231+
}

0 commit comments

Comments
 (0)