]> git.lizzy.rs Git - rust.git/commitdiff
Fall out of the std::sync rewrite
authorAlex Crichton <alex@alexcrichton.com>
Mon, 24 Nov 2014 19:16:40 +0000 (11:16 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 5 Dec 2014 17:12:25 +0000 (09:12 -0800)
19 files changed:
src/etc/licenseck.py
src/libstd/comm/mod.rs
src/libstd/comm/shared.rs
src/libstd/comm/stream.rs
src/libstd/dynamic_lib.rs
src/libstd/lib.rs
src/libstd/os.rs
src/libstd/rt/backtrace.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mutex.rs
src/libstd/sys/common/helper_thread.rs
src/libstd/sys/common/net.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/windows/mod.rs
src/libstd/sys/windows/mutex.rs
src/libstd/sys/windows/pipe.rs
src/test/bench/msgsend-ring-mutex-arcs.rs
src/test/bench/msgsend-ring-rw-arcs.rs [deleted file]

index 9162edcb53001631ede052c8a29b51564f6f8a1c..7669df36b041d9282aea7e22d7b0f771d7332e86 100644 (file)
@@ -38,9 +38,8 @@ exceptions = [
     "rt/isaac/randport.cpp", # public domain
     "rt/isaac/rand.h", # public domain
     "rt/isaac/standard.h", # public domain
-    "libstd/sync/mpsc_queue.rs", # BSD
-    "libstd/sync/spsc_queue.rs", # BSD
-    "libstd/sync/mpmc_bounded_queue.rs", # BSD
+    "libstd/comm/mpsc_queue.rs", # BSD
+    "libstd/comm/spsc_queue.rs", # BSD
     "test/bench/shootout-binarytrees.rs", # BSD
     "test/bench/shootout-chameneos-redux.rs", # BSD
     "test/bench/shootout-fannkuch-redux.rs", # BSD
index 2b66e91c00db05eadc1a06bf47a502775ef9ba2e..d291ed7256743b224a8e4a4806ce5fb3a6871973 100644 (file)
@@ -354,6 +354,8 @@ mod $name {
 mod shared;
 mod stream;
 mod sync;
+mod mpsc_queue;
+mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
 /// one task
@@ -628,24 +630,26 @@ pub fn send_opt(&self, t: T) -> Result<(), T> {
 #[unstable]
 impl<T: Send> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
-        let (packet, sleeper) = match *unsafe { self.inner() } {
+        let (packet, sleeper, guard) = match *unsafe { self.inner() } {
             Oneshot(ref p) => {
                 let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
                 unsafe {
-                    (*a.get()).postinit_lock();
+                    let guard = (*a.get()).postinit_lock();
                     match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
-                        oneshot::UpSuccess | oneshot::UpDisconnected => (a, None),
-                        oneshot::UpWoke(task) => (a, Some(task))
+                        oneshot::UpSuccess |
+                        oneshot::UpDisconnected => (a, None, guard),
+                        oneshot::UpWoke(task) => (a, Some(task), guard)
                     }
                 }
             }
             Stream(ref p) => {
                 let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
                 unsafe {
-                    (*a.get()).postinit_lock();
+                    let guard = (*a.get()).postinit_lock();
                     match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
-                        stream::UpSuccess | stream::UpDisconnected => (a, None),
-                        stream::UpWoke(task) => (a, Some(task)),
+                        stream::UpSuccess |
+                        stream::UpDisconnected => (a, None, guard),
+                        stream::UpWoke(task) => (a, Some(task), guard),
                     }
                 }
             }
@@ -657,7 +661,7 @@ fn clone(&self) -> Sender<T> {
         };
 
         unsafe {
-            (*packet.get()).inherit_blocker(sleeper);
+            (*packet.get()).inherit_blocker(sleeper, guard);
 
             let tmp = Sender::new(Shared(packet.clone()));
             mem::swap(self.inner_mut(), tmp.inner_mut());
index 6396edbdbd148eff3912c404475105662d650754..13b5e10fcd3dcd02cbf2ffb3a95a82cc005fb984 100644 (file)
 use core::cmp;
 use core::int;
 use rustrt::local::Local;
-use rustrt::mutex::NativeMutex;
 use rustrt::task::{Task, BlockedTask};
 use rustrt::thread::Thread;
 
-use sync::atomic;
-use sync::mpsc_queue as mpsc;
+use sync::{atomic, Mutex, MutexGuard};
+use comm::mpsc_queue as mpsc;
 
 const DISCONNECTED: int = int::MIN;
 const FUDGE: int = 1024;
@@ -56,7 +55,7 @@ pub struct Packet<T> {
 
     // this lock protects various portions of this implementation during
     // select()
-    select_lock: NativeMutex,
+    select_lock: Mutex<()>,
 }
 
 pub enum Failure {
@@ -76,7 +75,7 @@ pub fn new() -> Packet<T> {
             channels: atomic::AtomicInt::new(2),
             port_dropped: atomic::AtomicBool::new(false),
             sender_drain: atomic::AtomicInt::new(0),
-            select_lock: unsafe { NativeMutex::new() },
+            select_lock: Mutex::new(()),
         };
         return p;
     }
@@ -86,8 +85,8 @@ pub fn new() -> Packet<T> {
     // In other case mutex data will be duplicated while cloning
     // and that could cause problems on platforms where it is
     // represented by opaque data structure
-    pub fn postinit_lock(&mut self) {
-        unsafe { self.select_lock.lock_noguard() }
+    pub fn postinit_lock(&self) -> MutexGuard<()> {
+        self.select_lock.lock()
     }
 
     // This function is used at the creation of a shared packet to inherit a
@@ -95,7 +94,9 @@ pub fn postinit_lock(&mut self) {
     // tasks in select().
     //
     // This can only be called at channel-creation time
-    pub fn inherit_blocker(&mut self, task: Option<BlockedTask>) {
+    pub fn inherit_blocker(&mut self,
+                           task: Option<BlockedTask>,
+                           guard: MutexGuard<()>) {
         match task {
             Some(task) => {
                 assert_eq!(self.cnt.load(atomic::SeqCst), 0);
@@ -135,7 +136,7 @@ pub fn inherit_blocker(&mut self, task: Option<BlockedTask>) {
         // interfere with this method. After we unlock this lock, we're
         // signifying that we're done modifying self.cnt and self.to_wake and
         // the port is ready for the world to continue using it.
-        unsafe { self.select_lock.unlock_noguard() }
+        drop(guard);
     }
 
     pub fn send(&mut self, t: T) -> Result<(), T> {
@@ -441,7 +442,7 @@ pub fn abort_selection(&mut self, _was_upgrade: bool) -> bool {
         // done with. Without this bounce, we can race with inherit_blocker
         // about looking at and dealing with to_wake. Once we have acquired the
         // lock, we are guaranteed that inherit_blocker is done.
-        unsafe {
+        {
             let _guard = self.select_lock.lock();
         }
 
index 23d042960b16bbc37e0d47c8de77f5adc12cb957..06ab4f4427aa664a1e5c8b1edfc7c4bc903bcabf 100644 (file)
@@ -32,7 +32,7 @@
 use rustrt::thread::Thread;
 
 use sync::atomic;
-use sync::spsc_queue as spsc;
+use comm::spsc_queue as spsc;
 use comm::Receiver;
 
 const DISCONNECTED: int = int::MIN;
index 3cd0c0eeaf290b949180286e43a689b5f7dbd14e..160365dac361223453acc70d19c9b4790edece75 100644 (file)
@@ -225,8 +225,8 @@ pub unsafe fn open_internal() -> *mut u8 {
     }
 
     pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
-        use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+        use sync::{StaticMutex, MUTEX_INIT};
+        static LOCK: StaticMutex = MUTEX_INIT;
         unsafe {
             // dlerror isn't thread safe, so we need to lock around this entire
             // sequence
index f6b73f037f25b19d2b565e469a7c7cd0861b7fe5..d4274d7e4017e2a1b8dd9a461957f57099dc339a 100644 (file)
 #![allow(unknown_features)]
 #![feature(macro_rules, globs, linkage)]
 #![feature(default_type_params, phase, lang_items, unsafe_destructor)]
-#![feature(import_shadowing, slicing_syntax)]
+#![feature(import_shadowing, slicing_syntax, tuple_indexing)]
 
 // Don't link to std. We are std.
 #![no_std]
index 0abd030a16347e58b3f7e08462508c1bfceadd6e..a8adfec34ed683c48ed07f56e5244e4d14d4bd10 100644 (file)
@@ -209,14 +209,12 @@ pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD)
 Serialize access through a global lock.
 */
 fn with_env_lock<T>(f: || -> T) -> T {
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use sync::{StaticMutex, MUTEX_INIT};
 
-    static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
+    static LOCK: StaticMutex = MUTEX_INIT;
 
-    unsafe {
-        let _guard = LOCK.lock();
-        f()
-    }
+    let _guard = LOCK.lock();
+    f()
 }
 
 /// Returns a vector of (variable, value) pairs, for all the environment
index 0103fe670e76f73188d03be5598e6943fa1b0db1..159fc3080e836aba0adfbcb74a53d15e6c5a8233 100644 (file)
@@ -238,7 +238,7 @@ mod imp {
     use mem;
     use option::{Some, None, Option};
     use result::{Ok, Err};
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use sync::{StaticMutex, MUTEX_INIT};
 
     /// As always - iOS on arm uses SjLj exceptions and
     /// _Unwind_Backtrace is even not available there. Still,
@@ -264,8 +264,8 @@ fn backtrace(buf: *mut *mut libc::c_void,
         // while it doesn't requires lock for work as everything is
         // local, it still displays much nicer backtraces when a
         // couple of tasks panic simultaneously
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         try!(writeln!(w, "stack backtrace:"));
         // 100 lines should be enough
@@ -297,8 +297,8 @@ struct Context<'a> {
         // is semi-reasonable in terms of printing anyway, and we know that all
         // I/O done here is blocking I/O, not green I/O, so we don't have to
         // worry about this being a native vs green mutex.
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         try!(writeln!(w, "stack backtrace:"));
 
@@ -667,7 +667,7 @@ mod imp {
     use option::{Some, None};
     use path::Path;
     use result::{Ok, Err};
-    use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
+    use sync::{StaticMutex, MUTEX_INIT};
     use slice::SlicePrelude;
     use str::StrPrelude;
     use dynamic_lib::DynamicLibrary;
@@ -928,8 +928,8 @@ impl Drop for Cleanup {
     pub fn write(w: &mut Writer) -> IoResult<()> {
         // According to windows documentation, all dbghelp functions are
         // single-threaded.
-        static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        let _g = unsafe { LOCK.lock() };
+        static LOCK: StaticMutex = MUTEX_INIT;
+        let _g = LOCK.lock();
 
         // Open up dbghelp.dll, we don't link to it explicitly because it can't
         // always be found. Additionally, it's nice having fewer dependencies.
index 581b6b4e41202316276389e3428f7c205da95d87..0fdd57b27922c50d5e9068eb8a20bc413e1f45cb 100644 (file)
@@ -143,8 +143,14 @@ pub fn wait<T: AsMutexGuard>(&self, mutex_guard: &T) {
     ///
     /// Like `wait`, the lock specified will be re-acquired when this function
     /// returns, regardless of whether the timeout elapsed or not.
-    pub fn wait_timeout<T: AsMutexGuard>(&self, mutex_guard: &T,
-                                         dur: Duration) -> bool {
+    // Note that this method is *not* public, and this is quite intentional
+    // because we're not quite sure about the semantics of relative vs absolute
+    // durations or how the timing guarantees play into what the system APIs
+    // provide. There are also additional concerns about the unix-specific
+    // implementation which may need to be addressed.
+    #[allow(dead_code)]
+    fn wait_timeout<T: AsMutexGuard>(&self, mutex_guard: &T,
+                                     dur: Duration) -> bool {
         unsafe {
             let me: &'static Condvar = &*(self as *const _);
             me.inner.wait_timeout(mutex_guard, dur)
@@ -195,8 +201,9 @@ pub fn wait<T: AsMutexGuard>(&'static self, mutex_guard: &T) {
     /// specified duration.
     ///
     /// See `Condvar::wait_timeout`.
-    pub fn wait_timeout<T: AsMutexGuard>(&'static self, mutex_guard: &T,
-                                         dur: Duration) -> bool {
+    #[allow(dead_code)] // may want to stabilize this later, see wait_timeout above
+    fn wait_timeout<T: AsMutexGuard>(&'static self, mutex_guard: &T,
+                                     dur: Duration) -> bool {
         unsafe {
             let lock = mutex_guard.as_mutex_guard();
             let sys = mutex::guard_lock(lock);
index 3d17f2bc64b6eb435ecc69dd3358bb1ed1d24a0c..4e07d54c57e7d6b79b20be42006e4492180b05d1 100644 (file)
@@ -45,7 +45,7 @@
 /// let data = Arc::new(Mutex::new(0));
 ///
 /// let (tx, rx) = channel();
-/// for _ in range(0, 10) {
+/// for _ in range(0u, 10) {
 ///     let (data, tx) = (data.clone(), tx.clone());
 ///     spawn(proc() {
 ///         // The shared static can only be accessed once the lock is held.
index 9508d8d92325bab97d0022c4dc31a068a170552c..c0018c5d970421086eb86d70ad6ef17bf7f6254c 100644 (file)
 //! can be created in the future and there must be no active timers at that
 //! time.
 
+use prelude::*;
+
+use cell::UnsafeCell;
 use mem;
 use rustrt::bookkeeping;
-use rustrt::mutex::StaticNativeMutex;
 use rustrt;
-use cell::UnsafeCell;
+use sync::{StaticMutex, StaticCondvar};
 use sys::helper_signal;
-use prelude::*;
 
 use task;
 
@@ -39,7 +40,8 @@
 /// is for static initialization.
 pub struct Helper<M> {
     /// Internal lock which protects the remaining fields
-    pub lock: StaticNativeMutex,
+    pub lock: StaticMutex,
+    pub cond: StaticCondvar,
 
     // You'll notice that the remaining fields are UnsafeCell<T>, and this is
     // because all helper thread operations are done through &self, but we need
@@ -53,6 +55,9 @@ pub struct Helper<M> {
 
     /// Flag if this helper thread has booted and been initialized yet.
     pub initialized: UnsafeCell<bool>,
+
+    /// Flag if this helper thread has shut down
+    pub shutdown: UnsafeCell<bool>,
 }
 
 impl<M: Send> Helper<M> {
@@ -80,7 +85,9 @@ pub fn boot<T: Send>(&'static self,
                 task::spawn(proc() {
                     bookkeeping::decrement();
                     helper(receive, rx, t);
-                    self.lock.lock().signal()
+                    let _g = self.lock.lock();
+                    *self.shutdown.get() = true;
+                    self.cond.notify_one()
                 });
 
                 rustrt::at_exit(proc() { self.shutdown() });
@@ -119,7 +126,9 @@ fn shutdown(&'static self) {
             helper_signal::signal(*self.signal.get() as helper_signal::signal);
 
             // Wait for the child to exit
-            guard.wait();
+            while !*self.shutdown.get() {
+                self.cond.wait(&guard);
+            }
             drop(guard);
 
             // Clean up after ourselves
index 029fc8527426152cf61e6c073d240634c146c35b..ddc6dd021c30f7b178b2e7623e70639a6dc5b3c3 100644 (file)
 use mem;
 use num::Int;
 use ptr::{mod, null, null_mut};
-use rustrt::mutex;
 use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use io::net::addrinfo;
 use io::{IoResult, IoError};
 use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
+use sync::{Mutex, MutexGuard};
 use sys_common::{mod, keep_going, short_write, timeout};
 use prelude::*;
 use cmp;
@@ -557,12 +557,12 @@ struct Inner {
 
     // Unused on Linux, where this lock is not necessary.
     #[allow(dead_code)]
-    lock: mutex::NativeMutex
+    lock: Mutex<()>,
 }
 
 impl Inner {
     fn new(fd: sock_t) -> Inner {
-        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+        Inner { fd: fd, lock: Mutex::new(()) }
     }
 }
 
@@ -572,7 +572,7 @@ impl Drop for Inner {
 
 pub struct Guard<'a> {
     pub fd: sock_t,
-    pub guard: mutex::LockGuard<'a>,
+    pub guard: MutexGuard<'a, ()>,
 }
 
 #[unsafe_destructor]
@@ -666,7 +666,7 @@ fn lock_nonblocking(&self) {}
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock() },
+            guard: self.inner.lock.lock(),
         };
         assert!(set_nonblocking(self.fd(), true).is_ok());
         ret
@@ -805,7 +805,7 @@ fn lock_nonblocking(&self) {}
     fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
         let ret = Guard {
             fd: self.fd(),
-            guard: unsafe { self.inner.lock.lock() },
+            guard: self.inner.lock.lock(),
         };
         assert!(set_nonblocking(self.fd(), true).is_ok());
         ret
index 7b37fb3fb0f7c4e8fb0ff4707260823a513ae562..4effedbe3abd83635f0107bc2988572d74b25ee4 100644 (file)
 
 macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
     static $name: Helper<$m> = Helper {
-        lock: ::rustrt::mutex::NATIVE_MUTEX_INIT,
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
         chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
         signal: ::cell::UnsafeCell { value: 0 },
         initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
     };
 ) )
 
index 3f70fb5c1a56cf996b66de3ea386f7b35a59e154..08e6f7059d8c678c4d843f2faa1a3af3366b6ea0 100644 (file)
@@ -12,8 +12,7 @@
 use libc;
 use c_str::CString;
 use mem;
-use rustrt::mutex;
-use sync::atomic;
+use sync::{atomic, Mutex};
 use io::{mod, IoResult, IoError};
 use prelude::*;
 
@@ -60,12 +59,12 @@ struct Inner {
 
     // Unused on Linux, where this lock is not necessary.
     #[allow(dead_code)]
-    lock: mutex::NativeMutex
+    lock: Mutex<()>,
 }
 
 impl Inner {
     fn new(fd: fd_t) -> Inner {
-        Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
+        Inner { fd: fd, lock: Mutex::new(()) }
     }
 }
 
index e9243c5040c80643eaeac59f6a17888819dfa3bd..9fce308cb9468cad60def633aa6a3825ff412858 100644 (file)
 
 macro_rules! helper_init( (static $name:ident: Helper<$m:ty>) => (
     static $name: Helper<$m> = Helper {
-        lock: ::rustrt::mutex::NATIVE_MUTEX_INIT,
+        lock: ::sync::MUTEX_INIT,
+        cond: ::sync::CONDVAR_INIT,
         chan: ::cell::UnsafeCell { value: 0 as *mut Sender<$m> },
         signal: ::cell::UnsafeCell { value: 0 },
         initialized: ::cell::UnsafeCell { value: false },
+        shutdown: ::cell::UnsafeCell { value: false },
     };
 ) )
 
index 10ebcf4bd09767f79e336cc2c0c9360d31301566..ddd89070ed53d56ecff1c531f998a4d0022310d5 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use prelude::*;
+
 use sync::atomic;
 use alloc::{mod, heap};
 
@@ -21,8 +23,8 @@ pub struct Mutex { inner: atomic::AtomicUint }
 pub const MUTEX_INIT: Mutex = Mutex { inner: atomic::INIT_ATOMIC_UINT };
 
 #[inline]
-pub unsafe fn raw(m: &super::Mutex) -> ffi::LPCRITICAL_SECTION {
-    m.0.get()
+pub unsafe fn raw(m: &Mutex) -> ffi::LPCRITICAL_SECTION {
+    m.get()
 }
 
 impl Mutex {
index ca7985aa35bf8f94ba2af6a2066ce5bdc4b47661..bf658d0efd0290bd15345070f4e2f3cbbbd924b8 100644 (file)
@@ -89,8 +89,7 @@
 use c_str::CString;
 use mem;
 use ptr;
-use sync::atomic;
-use rustrt::mutex;
+use sync::{atomic, Mutex};
 use io::{mod, IoError, IoResult};
 use prelude::*;
 
@@ -126,7 +125,7 @@ fn drop(&mut self) {
 
 struct Inner {
     handle: libc::HANDLE,
-    lock: mutex::NativeMutex,
+    lock: Mutex<()>,
     read_closed: atomic::AtomicBool,
     write_closed: atomic::AtomicBool,
 }
@@ -135,7 +134,7 @@ impl Inner {
     fn new(handle: libc::HANDLE) -> Inner {
         Inner {
             handle: handle,
-            lock: unsafe { mutex::NativeMutex::new() },
+            lock: Mutex::new(()),
             read_closed: atomic::AtomicBool::new(false),
             write_closed: atomic::AtomicBool::new(false),
         }
index d06e6c8cd191fbf08bf0728a9a84b0889e6bd52c..863c3c879a7c108009e14604233c2dddfd962168 100644 (file)
 // ignore-lexer-test FIXME #15679
 
 use std::os;
-use std::sync::{Arc, Future, Mutex};
+use std::sync::{Arc, Future, Mutex, Condvar};
 use std::time::Duration;
 use std::uint;
 
 // A poor man's pipe.
-type pipe = Arc<Mutex<Vec<uint>>>;
+type pipe = Arc<(Mutex<Vec<uint>>, Condvar)>;
 
 fn send(p: &pipe, msg: uint) {
-    let mut arr = p.lock();
+    let &(ref lock, ref cond) = &**p;
+    let mut arr = lock.lock();
     arr.push(msg);
-    arr.cond.signal();
+    cond.notify_one();
 }
 fn recv(p: &pipe) -> uint {
-    let mut arr = p.lock();
+    let &(ref lock, ref cond) = &**p;
+    let mut arr = lock.lock();
     while arr.is_empty() {
-        arr.cond.wait();
+        cond.wait(&arr);
     }
     arr.pop().unwrap()
 }
 
 fn init() -> (pipe,pipe) {
-    let m = Arc::new(Mutex::new(Vec::new()));
+    let m = Arc::new((Mutex::new(Vec::new()), Condvar::new()));
     ((&m).clone(), m)
 }
 
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
deleted file mode 100644 (file)
index 03066d4..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// This test creates a bunch of tasks that simultaneously send to each
-// other in a ring. The messages should all be basically
-// independent.
-// This is like msgsend-ring-pipes but adapted to use Arcs.
-
-// This also serves as a pipes test, because Arcs are implemented with pipes.
-
-// no-pretty-expanded FIXME #15189
-// ignore-lexer-test FIXME #15679
-
-use std::os;
-use std::sync::{RWLock, Arc, Future};
-use std::time::Duration;
-use std::uint;
-
-// A poor man's pipe.
-type pipe = Arc<RWLock<Vec<uint>>>;
-
-fn send(p: &pipe, msg: uint) {
-    let mut arr = p.write();
-    arr.push(msg);
-    arr.cond.signal();
-}
-fn recv(p: &pipe) -> uint {
-    let mut arr = p.write();
-    while arr.is_empty() {
-        arr.cond.wait();
-    }
-    arr.pop().unwrap()
-}
-
-fn init() -> (pipe,pipe) {
-    let x = Arc::new(RWLock::new(Vec::new()));
-    ((&x).clone(), x)
-}
-
-
-fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
-    let mut num_chan = Some(num_chan);
-    let mut num_port = Some(num_port);
-    // Send/Receive lots of messages.
-    for j in range(0u, count) {
-        //println!("task %?, iter %?", i, j);
-        let num_chan2 = num_chan.take().unwrap();
-        let num_port2 = num_port.take().unwrap();
-        send(&num_chan2, i * j);
-        num_chan = Some(num_chan2);
-        let _n = recv(&num_port2);
-        //log(error, _n);
-        num_port = Some(num_port2);
-    };
-}
-
-fn main() {
-    let args = os::args();
-    let args = if os::getenv("RUST_BENCH").is_some() {
-        vec!("".to_string(), "100".to_string(), "10000".to_string())
-    } else if args.len() <= 1u {
-        vec!("".to_string(), "10".to_string(), "100".to_string())
-    } else {
-        args.clone().into_iter().collect()
-    };
-
-    let num_tasks = from_str::<uint>(args[1].as_slice()).unwrap();
-    let msg_per_task = from_str::<uint>(args[2].as_slice()).unwrap();
-
-    let (mut num_chan, num_port) = init();
-
-    let mut p = Some((num_chan, num_port));
-    let dur = Duration::span(|| {
-        let (mut num_chan, num_port) = p.take().unwrap();
-
-        // create the ring
-        let mut futures = Vec::new();
-
-        for i in range(1u, num_tasks) {
-            //println!("spawning %?", i);
-            let (new_chan, num_port) = init();
-            let num_chan_2 = num_chan.clone();
-            let new_future = Future::spawn(proc() {
-                thread_ring(i, msg_per_task, num_chan_2, num_port)
-            });
-            futures.push(new_future);
-            num_chan = new_chan;
-        };
-
-        // do our iteration
-        thread_ring(0, msg_per_task, num_chan, num_port);
-
-        // synchronize
-        for f in futures.iter_mut() {
-            let _ = f.get();
-        }
-    });
-
-    // all done, report stats.
-    let num_msgs = num_tasks * msg_per_task;
-    let rate = (num_msgs as f64) / (dur.num_milliseconds() as f64);
-
-    println!("Sent {} messages in {} ms", num_msgs, dur.num_milliseconds());
-    println!("  {} messages / second", rate / 1000.0);
-    println!("  {} μs / message", 1000000. / rate / 1000.0);
-}