Skip to content

Commit ed3ead0

Browse files
committed
Relax memory ordering of LOCAL_STREAMS and document it.
1 parent 07fd17f commit ed3ead0

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

library/std/src/io/stdio.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use crate::sys_common;
1616
use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
1717
use crate::thread::LocalKey;
1818

19-
static LOCAL_STREAMS: AtomicBool = AtomicBool::new(false);
20-
2119
thread_local! {
2220
/// Used by the test crate to capture the output of the print! and println! macros.
2321
static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
@@ -32,6 +30,20 @@ thread_local! {
3230
}
3331
}
3432

33+
/// Flag to indicate LOCAL_STDOUT and/or LOCAL_STDERR is used.
34+
///
35+
/// If both are None and were never set on any thread, this flag is set to
36+
/// false, and both LOCAL_STDOUT and LOCAL_STDOUT can be safely ignored on all
37+
/// threads, saving some time and memory registering an unused thread local.
38+
///
39+
/// Note about memory ordering: This contains information about whether two
40+
/// thread local variables might be in use. Although this is a global flag, the
41+
/// memory ordering between threads does not matter: we only want this flag to
42+
/// have a consistent order between set_print/set_panic and print_to *within
43+
/// the same thread*. Within the same thread, things always have a perfectly
44+
/// consistent order. So Ordering::Relaxed is fine.
45+
static LOCAL_STREAMS: AtomicBool = AtomicBool::new(false);
46+
3547
/// A handle to a raw instance of the standard input stream of this process.
3648
///
3749
/// 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 +
899911
Some(s)
900912
},
901913
);
902-
LOCAL_STREAMS.store(true, Ordering::Release);
914+
LOCAL_STREAMS.store(true, Ordering::Relaxed);
903915
s
904916
}
905917

@@ -926,7 +938,7 @@ pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write +
926938
Some(s)
927939
},
928940
);
929-
LOCAL_STREAMS.store(true, Ordering::Release);
941+
LOCAL_STREAMS.store(true, Ordering::Relaxed);
930942
s
931943
}
932944

@@ -949,7 +961,7 @@ fn print_to<T>(
949961
T: Write,
950962
{
951963
let result = LOCAL_STREAMS
952-
.load(Ordering::Acquire)
964+
.load(Ordering::Relaxed)
953965
.then(|| {
954966
local_s
955967
.try_with(|s| {

0 commit comments

Comments
 (0)