Skip to content

Commit ea94be6

Browse files
author
Greg Parker
committed
[runtime] Clean up documentation of the swift_once() implementation.
1 parent db45e57 commit ea94be6

File tree

2 files changed

+13
-12
lines changed

2 files changed

+13
-12
lines changed

lib/IRGen/SwiftTargetInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,12 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) {
133133
// Prepare generic target information.
134134
SwiftTargetInfo target(triple.getObjectFormat(), pointerSize);
135135

136-
// On Apple platforms, we implement "once" using dispatch_once, which exposes
137-
// -1 as ABI for the "done" value.
136+
// On Apple platforms, we implement "once" using dispatch_once,
137+
// which exposes a barrier-free inline path with -1 as the "done" value.
138138
if (triple.isOSDarwin())
139139
target.OnceDonePredicateValue = -1L;
140-
// TODO: Do we know this for Linux?
140+
// Other platforms use std::call_once() and we don't
141+
// assume that they have a barrier-free inline fast path.
141142

142143
switch (triple.getArch()) {
143144
case llvm::Triple::x86_64:

stdlib/public/runtime/Once.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@ using namespace swift;
2323

2424
#ifdef __APPLE__
2525

26-
// On OS X and iOS, swift_once is implemented using GCD.
26+
// On macOS and iOS, swift_once is implemented using GCD.
27+
// The compiler emits an inline check matching the barrier-free inline fast
28+
// path of dispatch_once(). See SwiftTargetInfo.OnceDonePredicateValue.
2729

2830
#include <dispatch/dispatch.h>
2931
static_assert(std::is_same<swift_once_t, dispatch_once_t>::value,
3032
"swift_once_t and dispatch_once_t must stay in sync");
33+
#else
34+
35+
// On non-Darwin platforms we do not assume any barrier-free inline path
36+
// and SwiftTargetInfo.OnceDonePredicateValue is unset in the compiler.
37+
3138
#endif
39+
3240
// The compiler generates the swift_once_t values as word-sized zero-initialized
3341
// variables, so we want to make sure swift_once_t isn't larger than the
3442
// platform word or the function below might overwrite something it shouldn't.
@@ -44,14 +52,6 @@ void swift::swift_once(swift_once_t *predicate, void (*fn)(void *)) {
4452
#elif defined(__CYGWIN__)
4553
_swift_once_f(predicate, nullptr, fn);
4654
#else
47-
// FIXME: We're relying here on the coincidence that libstdc++ uses pthread's
48-
// pthread_once, and that on glibc pthread_once follows a compatible init
49-
// process (the token is a word that is atomically incremented from 0 to
50-
// 1 to 2 during initialization) to work. We should implement our own version
51-
// that we can rely on to continue to work that way.
52-
// The MSVC port also relies on this, because the std::call_once on MSVC
53-
// follows the compatible init process.
54-
// For more information, see rdar://problem/18499385
5555
std::call_once(*predicate, [fn]() { fn(nullptr); });
5656
#endif
5757
}

0 commit comments

Comments
 (0)