diff options
| -rw-r--r-- | src/libcore/pipes.rs | 20 | ||||
| -rw-r--r-- | src/test/bench/pingpong.rs | 2 |
2 files changed, 18 insertions, 4 deletions
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 24eedf94746..d46452097bd 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -20,6 +20,8 @@ export select, select2, selecti, select2i, selectable; export spawn_service, spawn_service_recv; export stream, port, chan, shared_chan, port_set, channel; +const SPIN_COUNT: uint = 0; + macro_rules! move { { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } } @@ -272,7 +274,7 @@ unsafe fn get_buffer<T: send>(p: *packet_header) -> ~buffer<T> { class buffer_resource<T: send> { let buffer: ~buffer<T>; new(+b: ~buffer<T>) { - let p = ptr::addr_of(*b); + //let p = ptr::addr_of(*b); //#error("take %?", p); atomic_add_acq(b.header.ref_count, 1); self.buffer = b; @@ -280,7 +282,7 @@ class buffer_resource<T: send> { drop unsafe { let b = move!{self.buffer}; - let p = ptr::addr_of(*b); + //let p = ptr::addr_of(*b); //#error("drop %?", p); let old_count = atomic_sub_rel(b.header.ref_count, 1); //let old_count = atomic_xchng_rel(b.header.ref_count, 0); @@ -345,6 +347,7 @@ fn try_recv<T: send, Tbuffer: send>(-p: recv_packet_buffered<T, Tbuffer>) rustrt::task_clear_event_reject(this); p.header.blocked_task = some(this); let mut first = true; + let mut count = SPIN_COUNT; loop { rustrt::task_clear_event_reject(this); let old_state = swap_state_acq(p.header.state, @@ -352,7 +355,18 @@ fn try_recv<T: send, Tbuffer: send>(-p: recv_packet_buffered<T, Tbuffer>) alt old_state { empty { #debug("no data available on %?, going to sleep.", p_); - wait_event(this); + if count == 0 { + wait_event(this); + } + else { + count -= 1; + // FIXME (#524): Putting the yield here destroys a lot + // of the benefit of spinning, since we still go into + // the scheduler at every iteration. However, without + // this everything spins too much because we end up + // sometimes blocking the thing we are waiting on. + task::yield(); + } #debug("woke up, p.state = %?", copy p.header.state); } blocked { diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index 1c060621220..d6bd8562285 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -137,7 +137,7 @@ fn main() { let unbounded = do timeit { unbounded(count) }; io::println(#fmt("count: %?\n", count)); - io::println(#fmt("bounded: %? s\t(%? μs/message)", + io::println(#fmt("bounded: %? s\t(%? μs/message)", bounded, bounded * 1000000. / (count as float))); io::println(#fmt("unbounded: %? s\t(%? μs/message)", unbounded, unbounded * 1000000. / (count as float))); |
