Skip to content

Commit fd9cb75

Browse files
committed
[Threading] Fix some problems with the C11 threading code.
These changes are needed to get things building with a C11 threads shim header on macOS. rdar://90776105
1 parent fa8bed5 commit fd9cb75

File tree

15 files changed

+136
-51
lines changed

15 files changed

+136
-51
lines changed

include/swift/Threading/Impl/C11.h

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
#ifndef SWIFT_THREADING_IMPL_C11_H
1818
#define SWIFT_THREADING_IMPL_C11_H
1919

20-
#include <stdatomic.h>
20+
#include <atomic>
21+
#include <cstdint>
2122
#include <threads.h>
2223

24+
#include "swift/Threading/Errors.h"
25+
2326
namespace swift {
2427
namespace threading_impl {
2528

@@ -58,11 +61,9 @@ inline bool threads_same(thread_id a, thread_id b) {
5861
using mutex_handle = ::mtx_t;
5962

6063
inline void mutex_init(mutex_handle &handle, bool checked = false) {
61-
SWIFT_C11THREADS_CHECK(::mtx_init(&handle), ::mtx_plain);
62-
}
63-
inline void mutex_destroy(mutex_handle &handle) {
64-
SWIFT_C11THREADS_CHECK(::mtx_destroy(&handle));
64+
SWIFT_C11THREADS_CHECK(::mtx_init(&handle, ::mtx_plain));
6565
}
66+
inline void mutex_destroy(mutex_handle &handle) { ::mtx_destroy(&handle); }
6667

6768
inline void mutex_lock(mutex_handle &handle) {
6869
SWIFT_C11THREADS_CHECK(::mtx_lock(&handle));
@@ -83,33 +84,38 @@ inline void mutex_unsafe_unlock(mutex_handle &handle) {
8384

8485
struct lazy_mutex_handle {
8586
::mtx_t mutex;
86-
::atomic_int once; // -1 = initialized, 0 = uninitialized, 1 = initializing
87+
std::int32_t once; // -1 = initialized, 0 = uninitialized, 1 = initializing
8788
};
8889

8990
inline constexpr lazy_mutex_handle lazy_mutex_initializer() {
90-
return (lazy_mutex_handle){0};
91+
return (lazy_mutex_handle){};
9192
}
9293
inline void lazy_mutex_init(lazy_mutex_handle &handle) {
9394
// Sadly, we can't use call_once() for this as it doesn't have a context
94-
if (::atomic_load_explicit(&handle.once, ::memory_order_acquire) < 0)
95+
if (std::atomic_load_explicit((std::atomic<std::int32_t> *)&handle.once,
96+
std::memory_order_acquire) < 0)
9597
return;
9698

97-
if (::atomic_compare_exchange_strong_explicit(&handle.once, &(int){0}, 1,
98-
::memory_order_relaxed,
99-
::memory_order_relaxed)) {
99+
int zero = 0;
100+
if (std::atomic_compare_exchange_strong_explicit(
101+
(std::atomic<std::int32_t> *)&handle.once, &zero, 1,
102+
std::memory_order_relaxed, std::memory_order_relaxed)) {
100103
SWIFT_C11THREADS_CHECK(::mtx_init(&handle.mutex, ::mtx_plain));
101-
::atomic_store_explicit(&handle.once, -1, ::memory_order_release);
104+
std::atomic_store_explicit((std::atomic<std::int32_t> *)&handle.once, -1,
105+
std::memory_order_release);
102106
return;
103107
}
104108

105-
while (::atomic_load_explicit(&handle.once, memory_order_acquire) >= 0) {
109+
while (std::atomic_load_explicit((std::atomic<std::int32_t> *)&handle.once,
110+
std::memory_order_acquire) >= 0) {
106111
// Just spin; ::mtx_init() is very likely to be fast
107112
}
108113
}
109114

110115
inline void lazy_mutex_destroy(lazy_mutex_handle &handle) {
111-
if (::atomic_load_explicit(&handle.once, ::memory_order_acquire) < 0)
112-
SWIFT_C11THREADS_CHECK(::mtx_destroy(&handle.mutex));
116+
if (std::atomic_load_explicit((std::atomic<std::int32_t> *)&handle.once,
117+
std::memory_order_acquire) < 0)
118+
::mtx_destroy(&handle.mutex);
113119
}
114120

115121
inline void lazy_mutex_lock(lazy_mutex_handle &handle) {
@@ -136,20 +142,24 @@ inline void lazy_mutex_unsafe_unlock(lazy_mutex_handle &handle) {
136142

137143
// .. Once ...................................................................
138144

139-
typedef ::atomic_int once_t;
145+
typedef std::atomic<std::int64_t> once_t;
140146

141147
void once_slow(once_t &predicate, void (*fn)(void *), void *context);
142148

143149
inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
144150
// Sadly we can't use call_once() for this (no context)
145-
if (::atomic_load_explicit(&predicate, ::memory_order_acquire) < 0)
151+
if (std::atomic_load_explicit(&predicate, std::memory_order_acquire) < 0)
146152
return;
147153

148154
once_slow(predicate, fn, context);
149155
}
150156

151157
// .. Thread local storage ...................................................
152158

159+
// Get rid of this, because it causes clashes with TokenKinds.def
160+
#undef thread_local
161+
162+
// We *can* use the C++ version though
153163
#if __cplusplus >= 201103L || __has_feature(cxx_thread_local)
154164
#define SWIFT_THREAD_LOCAL thread_local
155165
#endif

include/swift/Threading/ThreadLocalStorage.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,18 @@ inline void tls_alloc_once(once_t &token, tls_key &key, tls_dtor dtor) {
8686

8787
// A wrapper class for thread-local storage.
8888
//
89-
// - On platforms that report SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL
90-
// above, an object of this type is declared with
91-
// SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL. This makes the object
89+
// - On platforms that define SWIFT_THREAD_LOCAL, an object of this type
90+
// is declared with SWIFT_THREAD_LOCAL. This makes the object
9291
// itself thread-local, and no internal support is required.
9392
//
9493
// Note that this includes platforms that don't support threading,
95-
// for which SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL is empty;
96-
// thread-local declarations then create an ordinary global.
94+
// for which SWIFT_THREAD_LOCAL is empty; thread-local declarations
95+
// then create an ordinary global.
9796
//
98-
// - On platforms that don't report SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL,
99-
// we have to simulate thread-local storage. Fortunately, all of
100-
// these platforms (at least for now) support pthread_getspecific
101-
// or similar.
102-
#if SWIFT_THREAD_LOCAL
97+
// - On platforms that don't define SWIFT_THREAD_LOCAL, we have to simulate
98+
// thread-local storage. Fortunately, all of these platforms (at least
99+
// for now) support pthread_getspecific or similar.
100+
#ifdef SWIFT_THREAD_LOCAL
103101
template <class T>
104102
class ThreadLocal {
105103
VALIDATE_THREAD_LOCAL_TYPE(T)
@@ -179,7 +177,7 @@ class ThreadLocal {
179177
/// Because of the fallback path, the default-initialization of the
180178
/// type must be equivalent to a bitwise zero-initialization, and the
181179
/// type must be small and trivially copyable and destructible.
182-
#if SWIFT_THREAD_LOCAL
180+
#ifdef SWIFT_THREAD_LOCAL
183181
#define SWIFT_THREAD_LOCAL_TYPE(TYPE, KEY) \
184182
SWIFT_THREAD_LOCAL swift::ThreadLocal<TYPE>
185183
#elif SWIFT_THREADING_USE_RESERVED_TLS_KEYS

lib/FrontendTool/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ target_link_libraries(swiftFrontendTool PRIVATE
2626
swiftSIL
2727
swiftSILGen
2828
swiftSILOptimizer
29-
swiftTBDGen)
29+
swiftTBDGen
30+
swiftThreading)
3031

3132
set_swift_llvm_is_available(swiftFrontendTool)

lib/Threading/C11.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
namespace {
2323

2424
#pragma clang diagnostic push
25-
#pragma GCC diagnostic ignored "-Wglobal-constructors"
25+
#pragma clang diagnostic ignored "-Wglobal-constructors"
2626

2727
class C11ThreadingHelper {
2828
private:
2929
thrd_t mainThread_;
30-
mut_t onceMutex_;
30+
mtx_t onceMutex_;
3131
cnd_t onceCond_;
3232

3333
public:
@@ -64,12 +64,13 @@ bool swift::threading_impl::thread_is_main() {
6464

6565
void swift::threading_impl::once_slow(once_t &predicate, void (*fn)(void *),
6666
void *context) {
67-
if (::atomic_compare_exchange_strong_explicit(&predicate, &(int){0}, 1,
68-
::memory_order_relaxed,
69-
::memory_order_relaxed)) {
67+
std::int64_t zero = 0;
68+
if (std::atomic_compare_exchange_strong_explicit(&predicate, &zero, 1,
69+
std::memory_order_relaxed,
70+
std::memory_order_relaxed)) {
7071
fn(context);
7172

72-
::atomic_store_explicit(&predicate, -1, ::memory_order_release);
73+
std::atomic_store_explicit(&predicate, -1, std::memory_order_release);
7374

7475
helper.once_lock();
7576
helper.once_unlock();
@@ -78,7 +79,8 @@ void swift::threading_impl::once_slow(once_t &predicate, void (*fn)(void *),
7879
}
7980

8081
helper.once_lock();
81-
while (::atomic_load_explicit(&predicate, memory_order_acquire) >= 0) {
82+
while (std::atomic_load_explicit(&predicate, std::memory_order_acquire) >=
83+
0) {
8284
helper.once_wait();
8385
}
8486
helper.once_unlock();

lib/Threading/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# If you update this, you also need to update the CMakeLists.txt file in
22
# stdlib/public/Threading
33

4+
# Note that it is *not* an error that Errors.cpp is only listed here.
5+
# It shouldn't be in stdlib/public/Threading because that is an OBJECT_LIBRARY
6+
# and things that use that should be defining their own fatal error handler.
7+
48
add_swift_host_library(swiftThreading STATIC
59
C11.cpp
610
Linux.cpp
711
Pthreads.cpp
8-
Win32.cpp)
12+
Win32.cpp
13+
Errors.cpp)

lib/Threading/Errors.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//==--- Errors.cpp - Threading implementation error handling --- -*-C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Provides a fallback definition of swift::threading::fatal(). You may
14+
// care to provide your own definition elsewhere, to tie the threading code's
15+
// error handling into the relevant code.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#include <cstdarg>
20+
#include <cstdio>
21+
#include <cstdlib>
22+
23+
#include "swift/Threading/Errors.h"
24+
25+
namespace swift {
26+
namespace threading {
27+
28+
SWIFT_ATTRIBUTE_NORETURN
29+
SWIFT_FORMAT(1, 2)
30+
void fatal(const char *msg, ...) {
31+
std::va_list val;
32+
33+
va_start(val, msg);
34+
std::vfprintf(stderr, msg, val);
35+
va_end(val);
36+
37+
std::abort();
38+
}
39+
40+
} // namespace threading
41+
} // namespace swift

stdlib/public/Concurrency/AsyncLet.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "swift/ABI/AsyncLet.h"
17+
#include "swift/Runtime/Concurrency.h"
18+
1819
#include "../CompatibilityOverride/CompatibilityOverride.h"
1920
#include "Debug.h"
2021
#include "TaskPrivate.h"
22+
23+
#include "swift/ABI/AsyncLet.h"
2124
#include "swift/ABI/Metadata.h"
2225
#include "swift/ABI/Task.h"
2326
#include "swift/ABI/TaskOptions.h"
24-
#include "swift/Runtime/Concurrency.h"
2527
#include "swift/Runtime/Heap.h"
2628
#include "swift/Runtime/HeapObject.h"
2729
#include "swift/Threading/Mutex.h"

stdlib/public/Threading/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,12 @@ add_swift_target_library(swiftThreading OBJECT_LIBRARY
77
"${SWIFT_SOURCE_DIR}/lib/Threading/Pthreads.cpp"
88
"${SWIFT_SOURCE_DIR}/lib/Threading/Win32.cpp"
99
INSTALL_IN_COMPONENT never_install)
10+
11+
# This is only used by the compatibility libraries
12+
add_swift_target_library(swiftThreadingWithFatal OBJECT_LIBRARY
13+
"${SWIFT_SOURCE_DIR}/lib/Threading/C11.cpp"
14+
"${SWIFT_SOURCE_DIR}/lib/Threading/Linux.cpp"
15+
"${SWIFT_SOURCE_DIR}/lib/Threading/Pthreads.cpp"
16+
"${SWIFT_SOURCE_DIR}/lib/Threading/Win32.cpp"
17+
"${SWIFT_SOURCE_DIR}/lib/Threading/Errors.cpp"
18+
INSTALL_IN_COMPONENT never_install)

stdlib/public/runtime/RuntimeInvocationsTracking.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18+
#include <cstdint>
19+
1820
#include "RuntimeInvocationsTracking.h"
1921
#include "swift/Basic/Lazy.h"
2022
#include "swift/Runtime/HeapObject.h"
@@ -32,7 +34,7 @@ namespace swift {
3234
// functions.
3335
struct RuntimeFunctionCountersState {
3436
#define FUNCTION_TO_TRACK(RT_FUNCTION) \
35-
uint32_t SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME(RT_FUNCTION) = 0;
37+
std::uint32_t SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME(RT_FUNCTION) = 0;
3638
// Provide one counter per runtime function being tracked.
3739
#include "RuntimeInvocationsTracking.def"
3840
};
@@ -73,7 +75,7 @@ static const char *RuntimeFunctionNames[] {
7375
/// Define an enum where each enumerator corresponds to a runtime function being
7476
/// tracked. Their order is the same as the order of the counters in the
7577
/// RuntimeObjectState structure.
76-
enum RuntimeFunctionNamesIDs : uint32_t {
78+
enum RuntimeFunctionNamesIDs : std::uint32_t {
7779
/// Defines names of enum cases for each function being tracked.
7880
#define FUNCTION_TO_TRACK(RT_FUNCTION) RT_FUNCTION_ID(RT_FUNCTION),
7981
#include "RuntimeInvocationsTracking.def"
@@ -87,10 +89,10 @@ static RuntimeFunctionCountersUpdateHandler
8789
/// The offsets of the runtime function counters being tracked inside the
8890
/// RuntimeObjectState structure. The array is indexed by
8991
/// the enumerators from RuntimeFunctionNamesIDs.
90-
static uint16_t RuntimeFunctionCountersOffsets[] = {
92+
static std::uint16_t RuntimeFunctionCountersOffsets[] = {
9193
/// Define offset for each function being tracked.
9294
#define FUNCTION_TO_TRACK(RT_FUNCTION) \
93-
(sizeof(uint16_t) * (unsigned)RT_FUNCTION_ID(RT_FUNCTION)),
95+
(sizeof(std::uint16_t) * (unsigned)RT_FUNCTION_ID(RT_FUNCTION)),
9496
#include "RuntimeInvocationsTracking.def"
9597
};
9698

@@ -169,17 +171,17 @@ const char **_swift_getRuntimeFunctionNames() {
169171
/// Return the offsets of the runtime function counters being tracked.
170172
/// Their order is the same as the order of the counters in the
171173
/// RuntimeObjectState structure.
172-
const uint16_t *_swift_getRuntimeFunctionCountersOffsets() {
174+
const std::uint16_t *_swift_getRuntimeFunctionCountersOffsets() {
173175
return RuntimeFunctionCountersOffsets;
174176
}
175177

176178
/// Return the number of runtime functions being tracked.
177-
uint64_t _swift_getNumRuntimeFunctionCounters() {
179+
std::uint64_t _swift_getNumRuntimeFunctionCounters() {
178180
return ID_LastRuntimeFunctionName;
179181
}
180182

181183
static void _swift_dumpRuntimeCounters(RuntimeFunctionCountersState *State) {
182-
uint32_t tmp;
184+
std::uint32_t tmp;
183185
/// Define how to dump the counter for a given runtime function.
184186
#define FUNCTION_TO_TRACK(RT_FUNCTION) \
185187
tmp = State->SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME(RT_FUNCTION); \

stdlib/public/stubs/Stubs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ __swift_bool _swift_stdlib_getCurrentStackBounds(__swift_uintptr_t *outBegin,
558558

559559
#elif SWIFT_THREADING_C11
560560
// We don't know any way to do this for C11 threads
561-
return false
561+
return false;
562562

563563
#elif SWIFT_THREADING_WIN32
564564

stdlib/toolchain/Compatibility50/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_swift_target_library("${library_name}" STATIC
88

99
C_COMPILE_FLAGS ${CXX_COMPILE_FLAGS}
1010
LINK_FLAGS ${CXX_LINK_FLAGS}
11+
INCORPORATE_OBJECT_LIBRARIES swiftThreadingWithFatal
1112
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
1213
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
1314
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}

stdlib/toolchain/Compatibility51/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ add_swift_target_library("${library_name}" STATIC
99

1010
C_COMPILE_FLAGS ${CXX_COMPILE_FLAGS}
1111
LINK_FLAGS ${CXX_LINK_FLAGS}
12+
INCORPORATE_OBJECT_LIBRARIES swiftThreadingWithFatal
1213
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
1314
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
1415
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}

stdlib/toolchain/CompatibilityConcurrency/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_swift_target_library("${library_name}" STATIC
77

88
C_COMPILE_FLAGS ${CXX_COMPILE_FLAGS}
99
LINK_FLAGS ${CXX_LINK_FLAGS}
10+
INCORPORATE_OBJECT_LIBRARIES swiftThreadingWithFatal
1011
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
1112
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
1213
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}

stdlib/toolchain/CompatibilityDynamicReplacements/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_swift_target_library("${library_name}" STATIC
77

88
C_COMPILE_FLAGS ${CXX_COMPILE_FLAGS}
99
LINK_FLAGS ${CXX_LINK_FLAGS}
10+
INCORPORATE_OBJECT_LIBRARIES swiftThreadingWithFatal
1011
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
1112
DEPLOYMENT_VERSION_OSX ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_OSX}
1213
DEPLOYMENT_VERSION_IOS ${COMPATIBILITY_MINIMUM_DEPLOYMENT_VERSION_IOS}

0 commit comments

Comments
 (0)