about summary refs log tree commit diff
path: root/src/libstd/sync
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2015-01-12 18:40:19 -0800
committerBrian Anderson <banderson@mozilla.com>2015-01-21 16:16:18 -0800
commit94ca8a361026d1a622a961e8dc8cacc331ed1ac3 (patch)
tree58179e85714f0a1ee618a8a9982aadbeb65822cf /src/libstd/sync
parent90aa581cff54ed1bb5f53ee2ead3764fca94fdf3 (diff)
downloadrust-94ca8a361026d1a622a961e8dc8cacc331ed1ac3.tar.gz
rust-94ca8a361026d1a622a961e8dc8cacc331ed1ac3.zip
Add 'feature' and 'since' to stability attributes
Diffstat (limited to 'src/libstd/sync')
-rw-r--r--src/libstd/sync/barrier.rs8
-rw-r--r--src/libstd/sync/condvar.rs40
-rw-r--r--src/libstd/sync/future.rs7
-rw-r--r--src/libstd/sync/mod.rs2
-rw-r--r--src/libstd/sync/mpsc/mod.rs56
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs4
-rw-r--r--src/libstd/sync/mpsc/select.rs13
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs2
-rw-r--r--src/libstd/sync/mutex.rs35
-rw-r--r--src/libstd/sync/once.rs6
-rw-r--r--src/libstd/sync/poison.rs20
-rw-r--r--src/libstd/sync/rwlock.rs53
-rw-r--r--src/libstd/sync/semaphore.rs7
-rw-r--r--src/libstd/sync/task_pool.rs9
14 files changed, 143 insertions, 119 deletions
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index 70939879400..c65a772da04 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -29,7 +29,7 @@ use sync::{Mutex, Condvar};
 ///     });
 /// }
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Barrier {
     lock: Mutex<BarrierState>,
     cvar: Condvar,
@@ -54,7 +54,7 @@ impl Barrier {
     ///
     /// A barrier will block `n`-1 threads which call `wait` and then wake up
     /// all threads at once when the `n`th thread calls `wait`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(n: uint) -> Barrier {
         Barrier {
             lock: Mutex::new(BarrierState {
@@ -75,7 +75,7 @@ impl Barrier {
     /// returns `true` from `is_leader` when returning from this function, and
     /// all other threads will receive a result that will return `false` from
     /// `is_leader`
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn wait(&self) -> BarrierWaitResult {
         let mut lock = self.lock.lock().unwrap();
         let local_gen = lock.generation_id;
@@ -102,7 +102,7 @@ impl BarrierWaitResult {
     ///
     /// Only one thread will have `true` returned from their result, all other
     /// threads will have `false` returned.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_leader(&self) -> bool { self.0 }
 }
 
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index d2d5335078e..739e70720ca 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -58,7 +58,7 @@ use sync::{mutex, MutexGuard};
 ///     started = cvar.wait(started).unwrap();
 /// }
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Condvar { inner: Box<StaticCondvar> }
 
 unsafe impl Send for Condvar {}
@@ -76,7 +76,8 @@ unsafe impl Sync for Condvar {}
 ///
 /// static CVAR: StaticCondvar = CONDVAR_INIT;
 /// ```
-#[unstable = "may be merged with Condvar in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Condvar in the future")]
 pub struct StaticCondvar {
     inner: sys::Condvar,
     mutex: AtomicUsize,
@@ -86,7 +87,8 @@ unsafe impl Send for StaticCondvar {}
 unsafe impl Sync for StaticCondvar {}
 
 /// Constant initializer for a statically allocated condition variable.
-#[unstable = "may be merged with Condvar in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Condvar in the future")]
 pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
     inner: sys::CONDVAR_INIT,
     mutex: ATOMIC_USIZE_INIT,
@@ -95,7 +97,7 @@ pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
     /// notified.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new() -> Condvar {
         Condvar {
             inner: box StaticCondvar {
@@ -131,7 +133,7 @@ impl Condvar {
     /// over time. Each condition variable is dynamically bound to exactly one
     /// mutex to ensure defined behavior across platforms. If this functionality
     /// is not desired, then unsafe primitives in `sys` are provided.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
         unsafe {
@@ -154,7 +156,7 @@ impl Condvar {
     ///
     /// Like `wait`, the lock specified will be re-acquired when this function
     /// returns, regardless of whether the timeout elapsed or not.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
                            -> LockResult<(MutexGuard<'a, T>, bool)> {
         unsafe {
@@ -169,7 +171,7 @@ impl Condvar {
     /// The semantics of this function are equivalent to `wait_timeout` except
     /// that the implementation will repeatedly wait while the duration has not
     /// passed and the provided function returns `false`.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn wait_timeout_with<'a, T, F>(&self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -189,7 +191,7 @@ impl Condvar {
     /// `notify_one` are not buffered in any way.
     ///
     /// To wake up all threads, see `notify_all()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
 
     /// Wake up all blocked threads on this condvar.
@@ -199,11 +201,11 @@ impl Condvar {
     /// way.
     ///
     /// To wake up only one thread, see `notify_one()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Drop for Condvar {
     fn drop(&mut self) {
         unsafe { self.inner.inner.destroy() }
@@ -215,7 +217,8 @@ impl StaticCondvar {
     /// notification.
     ///
     /// See `Condvar::wait`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
         let poisoned = unsafe {
@@ -235,7 +238,8 @@ impl StaticCondvar {
     /// specified duration.
     ///
     /// See `Condvar::wait_timeout`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration)
                                -> LockResult<(MutexGuard<'a, T>, bool)> {
         let (poisoned, success) = unsafe {
@@ -258,7 +262,8 @@ impl StaticCondvar {
     /// passed and the function returns `false`.
     ///
     /// See `Condvar::wait_timeout_with`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait_timeout_with<'a, T, F>(&'static self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -298,13 +303,15 @@ impl StaticCondvar {
     /// Wake up one blocked thread on this condvar.
     ///
     /// See `Condvar::notify_one`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
 
     /// Wake up all blocked threads on this condvar.
     ///
     /// See `Condvar::notify_all`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
 
     /// Deallocate all resources associated with this static condvar.
@@ -313,7 +320,8 @@ impl StaticCondvar {
     /// active users of the condvar, and this also doesn't prevent any future
     /// users of the condvar. This method is required to be called to not leak
     /// memory on all platforms.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub unsafe fn destroy(&'static self) {
         self.inner.destroy()
     }
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index 36bbc5ff5b4..bb309d5c2e8 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -27,9 +27,10 @@
 //! ```
 
 #![allow(missing_docs)]
-#![unstable = "futures as-is have yet to be deeply reevaluated with recent \
-               core changes to Rust's synchronization story, and will likely \
-               become stable in the future but are unstable until that time"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "futures as-is have yet to be deeply reevaluated with recent \
+                      core changes to Rust's synchronization story, and will likely \
+                      become stable in the future but are unstable until that time")]
 
 use core::prelude::*;
 use core::mem::replace;
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 6fff6765bd3..9e9d204aa46 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -15,7 +15,7 @@
 //! and/or blocking at all, but rather provide the necessary tools to build
 //! other types of concurrent primitives.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 pub use alloc::arc::{Arc, Weak};
 pub use core::atomic;
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 0ba19b70617..73ddd2e4c45 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -163,7 +163,7 @@
 //! }
 //! ```
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 // A description of how Rust's channel implementation works
 //
@@ -339,7 +339,7 @@ mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
 /// one task
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -351,14 +351,14 @@ unsafe impl<T:Send> Send for Receiver<T> { }
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Iter<'a, T:'a> {
     rx: &'a Receiver<T>
 }
 
 /// The sending-half of Rust's asynchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -369,8 +369,8 @@ unsafe impl<T:Send> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
     // can't share in an arc
@@ -379,7 +379,7 @@ pub struct SyncSender<T> {
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
@@ -394,7 +394,7 @@ impl<T> !marker::Sync for SyncSender<T> {}
 /// disconnected, implying that the data could never be received. The error
 /// contains the data being sent as a payload so it can be recovered.
 #[derive(PartialEq, Eq)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct SendError<T>(pub T);
 
 /// An error returned from the `recv` function on a `Receiver`.
@@ -402,29 +402,29 @@ pub struct SendError<T>(pub T);
 /// The `recv` operation can only fail if the sending half of a channel is
 /// disconnected, implying that no further messages will ever be received.
 #[derive(PartialEq, Eq, Clone, Copy)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RecvError;
 
 /// This enumeration is the list of the possible reasons that try_recv could not
 /// return data when called.
 #[derive(PartialEq, Clone, Copy)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TryRecvError {
     /// This channel is currently empty, but the sender(s) have not yet
     /// disconnected, so data may yet become available.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Empty,
 
     /// This channel's sending half has become disconnected, and there will
     /// never be any more data received on this channel
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Disconnected,
 }
 
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
 #[derive(PartialEq, Clone)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TrySendError<T> {
     /// The data could not be sent on the channel because it would require that
     /// the callee block to send the data.
@@ -432,12 +432,12 @@ pub enum TrySendError<T> {
     /// If this is a buffered channel, then the buffer is full at this time. If
     /// this is not a buffered channel, then there is no receiver available to
     /// acquire the data.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Full(T),
 
     /// This channel's receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Disconnected(T),
 }
 
@@ -495,7 +495,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// // Let's see what that answer was
 /// println!("{:?}", rx.recv().unwrap());
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
@@ -535,7 +535,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// assert_eq!(rx.recv().unwrap(), 1i);
 /// assert_eq!(rx.recv().unwrap(), 2i);
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
@@ -579,7 +579,7 @@ impl<T: Send> Sender<T> {
     /// drop(rx);
     /// assert_eq!(tx.send(1i).err().unwrap().0, 1);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         let (new_inner, ret) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -626,7 +626,7 @@ impl<T: Send> Sender<T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
@@ -672,7 +672,7 @@ impl<T: Send> Clone for Sender<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
@@ -713,7 +713,7 @@ impl<T: Send> SyncSender<T> {
     /// This function will never panic, but it may return `Err` if the
     /// `Receiver` has disconnected and is no longer able to receive
     /// information.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         unsafe { (*self.inner.get()).send(t).map_err(SendError) }
     }
@@ -727,13 +727,13 @@ impl<T: Send> SyncSender<T> {
     ///
     /// See `SyncSender::send` for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         unsafe { (*self.inner.get()).try_send(t) }
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
@@ -742,7 +742,7 @@ impl<T: Send> Clone for SyncSender<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
@@ -766,7 +766,7 @@ impl<T: Send> Receiver<T> {
     ///
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -827,7 +827,7 @@ impl<T: Send> Receiver<T> {
     /// If the corresponding `Sender` has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return `Err` to
     /// indicate that no more messages can ever be received on this channel.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn recv(&self) -> Result<T, RecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -866,7 +866,7 @@ impl<T: Send> Receiver<T> {
 
     /// Returns an iterator that will block waiting for messages, but never
     /// `panic!`. It will return `None` when the channel has hung up.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { rx: self }
     }
@@ -958,7 +958,7 @@ impl<T: Send> select::Packet for Receiver<T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T: Send> Iterator for Iter<'a, T> {
     type Item = T;
 
@@ -966,7 +966,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index 83de98fdbff..9747de3b7f9 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -35,7 +35,7 @@
 //! method, and see the method for more information about it. Due to this
 //! caveat, this queue may not be appropriate for all use-cases.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 // http://www.1024cores.net/home/lock-free-algorithms
 //                         /queues/non-intrusive-mpsc-node-based-queue
@@ -138,7 +138,7 @@ impl<T: Send> Queue<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index 62a7b823ec8..1a433db2deb 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -46,12 +46,13 @@
 //! ```
 
 #![allow(dead_code)]
-#![unstable = "This implementation, while likely sufficient, is unsafe and \
-                   likely to be error prone. At some point in the future this \
-                   module will likely be replaced, and it is currently \
-                   unknown how much API breakage that will cause. The ability \
-                   to select over a number of channels will remain forever, \
-                   but no guarantees beyond this are being made"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "This implementation, while likely sufficient, is unsafe and \
+                      likely to be error prone. At some point in the future this \
+                      module will likely be replaced, and it is currently \
+                      unknown how much API breakage that will cause. The ability \
+                      to select over a number of channels will remain forever, \
+                      but no guarantees beyond this are being made")]
 
 
 use core::prelude::*;
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index 34fd6bb70dc..cc7a34f8d4c 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -33,7 +33,7 @@
 //! concurrently between two tasks. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use core::prelude::*;
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 73d5332d16f..343dfbf68c7 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -109,7 +109,7 @@ use sys_common::mutex as sys;
 ///
 /// *guard += 1;
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Mutex<T> {
     // Note that this static mutex is in a *box*, not inlined into the struct
     // itself. Once a native mutex has been used once, its address can never
@@ -145,7 +145,8 @@ unsafe impl<T:Send> Sync for Mutex<T> { }
 /// }
 /// // lock is unlocked here.
 /// ```
-#[unstable = "may be merged with Mutex in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Mutex in the future")]
 pub struct StaticMutex {
     lock: sys::Mutex,
     poison: poison::Flag,
@@ -159,8 +160,8 @@ unsafe impl Sync for StaticMutex {}
 /// The data protected by the mutex can be access through this guard via its
 /// Deref and DerefMut implementations
 #[must_use]
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct MutexGuard<'a, T: 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
@@ -176,7 +177,7 @@ pub struct MutexGuard<'a, T: 'a> {
 /// The data protected by the mutex can be access through this guard via its
 /// Deref and DerefMut implementations
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct MutexGuard<'a, T: 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
@@ -191,7 +192,8 @@ impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
 
 /// Static initialization of a mutex. This constant can be used to initialize
 /// other mutex constants.
-#[unstable = "may be merged with Mutex in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Mutex in the future")]
 pub const MUTEX_INIT: StaticMutex = StaticMutex {
     lock: sys::MUTEX_INIT,
     poison: poison::FLAG_INIT,
@@ -199,7 +201,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex {
 
 impl<T: Send> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
         Mutex {
             inner: box MUTEX_INIT,
@@ -218,7 +220,7 @@ impl<T: Send> Mutex<T> {
     ///
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return an error once the mutex is acquired.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe { self.inner.lock.lock() }
         MutexGuard::new(&*self.inner, &self.data)
@@ -237,7 +239,7 @@ impl<T: Send> Mutex<T> {
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return failure if the mutex would otherwise be
     /// acquired.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         if unsafe { self.inner.lock.try_lock() } {
             Ok(try!(MutexGuard::new(&*self.inner, &self.data)))
@@ -248,7 +250,7 @@ impl<T: Send> Mutex<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
@@ -265,7 +267,8 @@ static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
 impl StaticMutex {
     /// Acquires this lock, see `Mutex::lock`
     #[inline]
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
         unsafe { self.lock.lock() }
         MutexGuard::new(self, &DUMMY.0)
@@ -273,7 +276,8 @@ impl StaticMutex {
 
     /// Attempts to grab this lock, see `Mutex::try_lock`
     #[inline]
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
         if unsafe { self.lock.try_lock() } {
             Ok(try!(MutexGuard::new(self, &DUMMY.0)))
@@ -292,7 +296,8 @@ impl StaticMutex {
     /// *all* platforms. It may be the case that some platforms do not leak
     /// memory if this method is not called, but this is not guaranteed to be
     /// true on all platforms.
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
@@ -325,7 +330,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
@@ -333,7 +338,7 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
         unsafe { &*self.__data.get() }
     }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.__data.get() }
@@ -341,7 +346,7 @@ impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 6231a91833d..82ed62966b5 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -36,7 +36,7 @@ use sync::{StaticMutex, MUTEX_INIT};
 ///     // run initialization here
 /// });
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Once {
     mutex: StaticMutex,
     cnt: AtomicIsize,
@@ -46,7 +46,7 @@ pub struct Once {
 unsafe impl Sync for Once {}
 
 /// Initialization value for static `Once` values.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub const ONCE_INIT: Once = Once {
     mutex: MUTEX_INIT,
     cnt: ATOMIC_ISIZE_INIT,
@@ -63,7 +63,7 @@ impl Once {
     ///
     /// When this function returns, it is guaranteed that some initialization
     /// has run and completed (it may not be the closure specified).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
         // Optimize common path: load is much cheaper than fetch_add.
         if self.cnt.load(Ordering::SeqCst) < 0 {
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
index e28c3c37b6f..4443fc2be60 100644
--- a/src/libstd/sync/poison.rs
+++ b/src/libstd/sync/poison.rs
@@ -53,22 +53,22 @@ pub struct Guard {
 /// is held. The precise semantics for when a lock is poisoned is documented on
 /// each lock, but once a lock is poisoned then all future acquisitions will
 /// return this error.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct PoisonError<T> {
     guard: T,
 }
 
 /// An enumeration of possible errors which can occur while calling the
 /// `try_lock` method.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TryLockError<T> {
     /// The lock could not be acquired because another task failed while holding
     /// the lock.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Poisoned(PoisonError<T>),
     /// The lock could not be acquired at this time because the operation would
     /// otherwise block.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     WouldBlock,
 }
 
@@ -79,7 +79,7 @@ pub enum TryLockError<T> {
 /// that the primitive was poisoned. Note that the `Err` variant *also* carries
 /// the associated guard, and it can be acquired through the `into_inner`
 /// method.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 
 /// A type alias for the result of a nonblocking locking method.
@@ -87,7 +87,7 @@ pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 /// For more information, see `LockResult`. A `TryLockResult` doesn't
 /// necessarily hold the associated guard in the `Err` type as the lock may not
 /// have been acquired for other reasons.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
 
 impl<T> fmt::Show for PoisonError<T> {
@@ -105,22 +105,22 @@ impl<T> Error for PoisonError<T> {
 impl<T> PoisonError<T> {
     /// Consumes this error indicating that a lock is poisoned, returning the
     /// underlying guard to allow access regardless.
-    #[deprecated="renamed to into_inner"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "renamed to into_inner")]
     pub fn into_guard(self) -> T { self.guard }
 
     /// Consumes this error indicating that a lock is poisoned, returning the
     /// underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn into_inner(self) -> T { self.guard }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
     /// reference to the underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn get_ref(&self) -> &T { &self.guard }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
     /// mutable reference to the underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
 }
 
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 237f6d08a95..6d0b34b3c87 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -58,7 +58,7 @@ use sys_common::rwlock as sys;
 ///     assert_eq!(*w, 6);
 /// } // write lock is dropped here
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLock<T> {
     inner: Box<StaticRwLock>,
     data: UnsafeCell<T>,
@@ -90,7 +90,8 @@ unsafe impl<T> Sync for RwLock<T> {}
 /// }
 /// unsafe { LOCK.destroy() } // free all resources
 /// ```
-#[unstable = "may be merged with RwLock in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with RwLock in the future")]
 pub struct StaticRwLock {
     lock: sys::RWLock,
     poison: poison::Flag,
@@ -100,7 +101,8 @@ unsafe impl Send for StaticRwLock {}
 unsafe impl Sync for StaticRwLock {}
 
 /// Constant initialization for a statically-initialized rwlock.
-#[unstable = "may be merged with RwLock in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with RwLock in the future")]
 pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
     lock: sys::RWLOCK_INIT,
     poison: poison::FLAG_INIT,
@@ -109,7 +111,7 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
 pub struct RwLockReadGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
@@ -120,8 +122,8 @@ pub struct RwLockReadGuard<'a, T: 'a> {
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLockReadGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
@@ -133,8 +135,8 @@ impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {}
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLockWriteGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
@@ -145,7 +147,7 @@ pub struct RwLockWriteGuard<'a, T: 'a> {
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct RwLockWriteGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
@@ -158,7 +160,7 @@ impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
 
 impl<T: Send + Sync> RwLock<T> {
     /// Creates a new instance of an RwLock which is unlocked and read to go.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
         RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
     }
@@ -181,7 +183,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// The failure will occur immediately after the lock has been acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe { self.inner.lock.read() }
         RwLockReadGuard::new(&*self.inner, &self.data)
@@ -203,7 +205,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
             Ok(try!(RwLockReadGuard::new(&*self.inner, &self.data)))
@@ -227,7 +229,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// An error will be returned when the lock is acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe { self.inner.lock.write() }
         RwLockWriteGuard::new(&*self.inner, &self.data)
@@ -246,7 +248,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
             Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data)))
@@ -257,7 +259,7 @@ impl<T: Send + Sync> RwLock<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T> Drop for RwLock<T> {
     fn drop(&mut self) {
         unsafe { self.inner.lock.destroy() }
@@ -274,7 +276,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::read`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
         unsafe { self.lock.read() }
         RwLockReadGuard::new(self, &DUMMY.0)
@@ -284,7 +287,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::try_read`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn try_read(&'static self)
                     -> TryLockResult<RwLockReadGuard<'static, ()>> {
         if unsafe { self.lock.try_read() } {
@@ -299,7 +303,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::write`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
         unsafe { self.lock.write() }
         RwLockWriteGuard::new(self, &DUMMY.0)
@@ -309,7 +314,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::try_write`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn try_write(&'static self)
                      -> TryLockResult<RwLockWriteGuard<'static, ()>> {
         if unsafe { self.lock.try_write() } {
@@ -325,7 +331,8 @@ impl StaticRwLock {
     /// active users of the lock, and this also doesn't prevent any future users
     /// of this lock. This method is required to be called to not leak memory on
     /// all platforms.
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
@@ -382,19 +389,19 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.__data.get() }
@@ -402,7 +409,7 @@ impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
         unsafe { self.__lock.lock.read_unlock(); }
@@ -410,7 +417,7 @@ impl<'a, T> Drop for RwLockReadGuard<'a, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs
index 8d44084671a..08b620c764a 100644
--- a/src/libstd/sync/semaphore.rs
+++ b/src/libstd/sync/semaphore.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable = "the interaction between semaphores and the acquisition/release \
-               of resources is currently unclear"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "the interaction between semaphores and the acquisition/release \
+                      of resources is currently unclear")]
 
 use ops::Drop;
 use sync::{Mutex, Condvar};
@@ -99,7 +100,7 @@ impl Semaphore {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a> Drop for SemaphoreGuard<'a> {
     fn drop(&mut self) {
         self.sem.release();
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index 278528bdb38..ceec1885375 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -10,10 +10,11 @@
 
 //! Abstraction of a thread pool for basic parallelism.
 
-#![unstable = "the semantics of a failing task and whether a thread is \
-               re-attached to a thread pool are somewhat unclear, and the \
-               utility of this type in `std::sync` is questionable with \
-               respect to the jobs of other primitives"]
+#![unstable(feature = "unnamed_feature", since="1.0.0",
+            reason = "the semantics of a failing task and whether a thread is \
+                      re-attached to a thread pool are somewhat unclear, and the \
+                      utility of this type in `std::sync` is questionable with \
+                      respect to the jobs of other primitives")]
 
 use core::prelude::*;