diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-09-27 15:32:07 +0200 |
|---|---|---|
| committer | Mara Bos <m-ou.se@m-ou.se> | 2020-09-27 16:04:25 +0200 |
| commit | ed3ead013f40c65e2972c794a71b756237a31b46 (patch) | |
| tree | fb41a1e0d25cf184248617a5109cd35bd0e1915c /library/std | |
| parent | 07fd17f7014de6dc209c7dc4de159a2a5acea173 (diff) | |
| download | rust-ed3ead013f40c65e2972c794a71b756237a31b46.tar.gz rust-ed3ead013f40c65e2972c794a71b756237a31b46.zip | |
Relax memory ordering of LOCAL_STREAMS and document it.
Diffstat (limited to 'library/std')
| -rw-r--r-- | library/std/src/io/stdio.rs | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 814e0dfda54..df83c329829 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -16,8 +16,6 @@ use crate::sys_common; use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; use crate::thread::LocalKey; -static LOCAL_STREAMS: AtomicBool = AtomicBool::new(false); - thread_local! { /// Used by the test crate to capture the output of the print! and println! macros. static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = { @@ -32,6 +30,20 @@ thread_local! { } } +/// Flag to indicate LOCAL_STDOUT and/or LOCAL_STDERR is used. +/// +/// If both are None and were never set on any thread, this flag is set to +/// false, and both LOCAL_STDOUT and LOCAL_STDOUT can be safely ignored on all +/// threads, saving some time and memory registering an unused thread local. +/// +/// Note about memory ordering: This contains information about whether two +/// thread local variables might be in use. Although this is a global flag, the +/// memory ordering between threads does not matter: we only want this flag to +/// have a consistent order between set_print/set_panic and print_to *within +/// the same thread*. Within the same thread, things always have a perfectly +/// consistent order. So Ordering::Relaxed is fine. +static LOCAL_STREAMS: AtomicBool = AtomicBool::new(false); + /// A handle to a raw instance of the standard input stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via @@ -899,7 +911,7 @@ pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Some(s) }, ); - LOCAL_STREAMS.store(true, Ordering::Release); + LOCAL_STREAMS.store(true, Ordering::Relaxed); s } @@ -926,7 +938,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Some(s) }, ); - LOCAL_STREAMS.store(true, Ordering::Release); + LOCAL_STREAMS.store(true, Ordering::Relaxed); s } @@ -949,7 +961,7 @@ fn print_to<T>( T: Write, { let result = LOCAL_STREAMS - .load(Ordering::Acquire) + .load(Ordering::Relaxed) .then(|| { local_s .try_with(|s| { |
