]> git.lizzy.rs Git - rust.git/commitdiff
Added infrastructure to spin for a bit on recv. A spin count > 0 makes bench/pingpong...
authorEric Holk <eric.holk@gmail.com>
Tue, 24 Jul 2012 16:35:44 +0000 (09:35 -0700)
committerEric Holk <eric.holk@gmail.com>
Wed, 25 Jul 2012 19:12:25 +0000 (12:12 -0700)
src/libcore/pipes.rs
src/test/bench/pingpong.rs

index 24eedf947461b20f30496b60c37354921c557388..d46452097bd631645193244406c84e984881e728 100644 (file)
@@ -20,6 +20,8 @@
 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 @@ unsafe fn get_buffer<T: send>(p: *packet_header) -> ~buffer<T> {
 
     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 {
index 1c06062122088ef4ad477fda96ad7ed0faacb829..d6bd85622852c050a50dde061d0e576dce1cf9f9 100644 (file)
@@ -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)));