Skip to content

Commit 766c5cd

Browse files
committed
swift_once implemented
1 parent 641bc2a commit 766c5cd

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

include/swift/Runtime/Once.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ namespace swift {
2727
// On OS X and iOS, swift_once_t matches dispatch_once_t.
2828
typedef long swift_once_t;
2929

30+
#elif defined(__CYGWIN__)
31+
32+
// On Cygwin, std::once_flag can not be used because it is larger than the
33+
// platform word.
34+
typedef unsigned long swift_once_t;
3035
#else
3136

3237
// On other platforms swift_once_t is std::once_flag

stdlib/public/runtime/Once.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include "swift/Runtime/Once.h"
1818
#include "swift/Runtime/Debug.h"
1919
#include <type_traits>
20+
#if defined(__CYGWIN__)
21+
#include <mutex>
22+
#endif
2023

2124
using namespace swift;
2225

@@ -31,9 +34,11 @@ static_assert(std::is_same<swift_once_t, dispatch_once_t>::value,
3134
// The compiler generates the swift_once_t values as word-sized zero-initialized
3235
// variables, so we want to make sure swift_once_t isn't larger than the
3336
// platform word or the function below might overwrite something it shouldn't.
34-
#if !defined(__CYGWIN__)
3537
static_assert(sizeof(swift_once_t) <= sizeof(void*),
3638
"swift_once_t must be no larger than the platform word");
39+
40+
#if defined(__CYGWIN__)
41+
static std::mutex mutex_;
3742
#endif
3843

3944
/// Runs the given function with the given context argument exactly once.
@@ -42,6 +47,18 @@ static_assert(sizeof(swift_once_t) <= sizeof(void*),
4247
void swift::swift_once(swift_once_t *predicate, void (*fn)(void *)) {
4348
#if defined(__APPLE__)
4449
dispatch_once_f(predicate, nullptr, fn);
50+
#else
51+
#if defined(__CYGWIN__)
52+
53+
mutex_.lock();
54+
if (*predicate == 0) {
55+
*predicate = 1ul;
56+
mutex_.unlock();
57+
58+
fn(nullptr);
59+
} else
60+
mutex_.unlock();
61+
4562
#else
4663
// FIXME: We're relying here on the coincidence that libstdc++ uses pthread's
4764
// pthread_once, and that on glibc pthread_once follows a compatible init
@@ -51,4 +68,5 @@ void swift::swift_once(swift_once_t *predicate, void (*fn)(void *)) {
5168
// For more information, see rdar://problem/18499385
5269
std::call_once(*predicate, [fn]() { fn(nullptr); });
5370
#endif
71+
#endif
5472
}

0 commit comments

Comments
 (0)