Skip to content

Commit f5be06f

Browse files
committed
Added infrastructure to spin for a bit on recv. A spin count > 0 makes bench/pingpong.rs about 10x faster, but makes msgsend-ring-pipes unbearably slow.
1 parent 3557616 commit f5be06f

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/libcore/pipes.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export select, select2, selecti, select2i, selectable;
2020
export spawn_service, spawn_service_recv;
2121
export stream, port, chan, shared_chan, port_set, channel;
2222

23+
const SPIN_COUNT: uint = 0;
24+
2325
macro_rules! move {
2426
{ $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
2527
}
@@ -272,15 +274,15 @@ unsafe fn get_buffer<T: send>(p: *packet_header) -> ~buffer<T> {
272274
class buffer_resource<T: send> {
273275
let buffer: ~buffer<T>;
274276
new(+b: ~buffer<T>) {
275-
let p = ptr::addr_of(*b);
277+
//let p = ptr::addr_of(*b);
276278
//#error("take %?", p);
277279
atomic_add_acq(b.header.ref_count, 1);
278280
self.buffer = b;
279281
}
280282

281283
drop unsafe {
282284
let b = move!{self.buffer};
283-
let p = ptr::addr_of(*b);
285+
//let p = ptr::addr_of(*b);
284286
//#error("drop %?", p);
285287
let old_count = atomic_sub_rel(b.header.ref_count, 1);
286288
//let old_count = atomic_xchng_rel(b.header.ref_count, 0);
@@ -345,14 +347,26 @@ fn try_recv<T: send, Tbuffer: send>(-p: recv_packet_buffered<T, Tbuffer>)
345347
rustrt::task_clear_event_reject(this);
346348
p.header.blocked_task = some(this);
347349
let mut first = true;
350+
let mut count = SPIN_COUNT;
348351
loop {
349352
rustrt::task_clear_event_reject(this);
350353
let old_state = swap_state_acq(p.header.state,
351354
blocked);
352355
alt old_state {
353356
empty {
354357
#debug("no data available on %?, going to sleep.", p_);
355-
wait_event(this);
358+
if count == 0 {
359+
wait_event(this);
360+
}
361+
else {
362+
count -= 1;
363+
// FIXME (#524): Putting the yield here destroys a lot
364+
// of the benefit of spinning, since we still go into
365+
// the scheduler at every iteration. However, without
366+
// this everything spins too much because we end up
367+
// sometimes blocking the thing we are waiting on.
368+
task::yield();
369+
}
356370
#debug("woke up, p.state = %?", copy p.header.state);
357371
}
358372
blocked {

src/test/bench/pingpong.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ fn main() {
137137
let unbounded = do timeit { unbounded(count) };
138138

139139
io::println(#fmt("count: %?\n", count));
140-
io::println(#fmt("bounded: %? s\t(%? μs/message)",
140+
io::println(#fmt("bounded: %? s\t(%? μs/message)",
141141
bounded, bounded * 1000000. / (count as float)));
142142
io::println(#fmt("unbounded: %? s\t(%? μs/message)",
143143
unbounded, unbounded * 1000000. / (count as float)));

0 commit comments

Comments
 (0)