Skip to content

Commit 5a326f9

Browse files
committed
[Runtime] Faster dynamic exclusivity checking implemented in Swift.
Replace C++ implementation of swift_beginAccess and swift_endAccess with (almost) pure Swift implementation. Helpers remain in C++ for TLS, getting return addresses, and raising a fatal error on violations. This change also moves the exclusivity access set head from the shared SwiftTLSContext structure to a dedicated TLS key. This improves performance, which is important for exclusivity checking. This is particularly the case where we can inline TLS access with a constant key, as on Darwin ARM64. The code that bridges exclusivity tracking into Concurrency remains in C++. The new Swift implementation exposes a few helpers for it to use as a replacement for directly manipulating the C++ implementation. rdar://161122309
1 parent e2287b6 commit 5a326f9

File tree

16 files changed

+395
-311
lines changed

16 files changed

+395
-311
lines changed

Runtimes/Core/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ add_library(swiftCore
7474
EmptyCollection.swift
7575
EnumeratedSequence.swift
7676
Equatable.swift
77+
Exclusivity.swift
7778
ErrorType.swift
7879
ExistentialCollection.swift
7980
Filter.swift

include/swift/Threading/Impl/Darwin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ inline tls_key_t tls_get_key(tls_key k) {
285285
return __PTK_FRAMEWORK_SWIFT_KEY5;
286286
case tls_key::observation_transaction:
287287
return __PTK_FRAMEWORK_SWIFT_KEY6;
288+
case tls_key::exclusivity:
289+
return __PTK_FRAMEWORK_SWIFT_KEY7;
288290
}
289291
}
290292

include/swift/Threading/TLSKeys.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ enum class tls_key {
2222
concurrency_task,
2323
concurrency_executor_tracking_info,
2424
concurrency_fallback,
25-
observation_transaction
25+
observation_transaction,
26+
exclusivity,
2627
};
2728

2829
} // namespace swift

stdlib/public/SwiftShims/swift/shims/AssertionReporting.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ void _swift_stdlib_reportUnimplementedInitializer(
6868
const unsigned char *initName, int initNameLength,
6969
__swift_uint32_t flags);
7070

71+
SWIFT_RUNTIME_STDLIB_SPI
72+
void _swift_reportExclusivityConflict(__swift_uintptr_t oldAction,
73+
const void *_Nullable oldPC,
74+
__swift_uintptr_t newFlags,
75+
const void *_Nullable newPC,
76+
const void *_Nullable pointer);
77+
7178
#ifdef __cplusplus
7279
} // extern "C"
7380
#endif

stdlib/public/SwiftShims/swift/shims/LibcShims.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ SWIFT_RUNTIME_STDLIB_INTERNAL
3838
__swift_size_t _swift_stdlib_fwrite_stdout(const void *ptr, __swift_size_t size,
3939
__swift_size_t nitems);
4040

41+
SWIFT_RUNTIME_STDLIB_INTERNAL
42+
void _swift_stdlib_fputs_stderr(const char *str);
43+
4144
// General utilities <stdlib.h>
4245
// Memory management functions
4346
static inline void _swift_stdlib_free(void *_Nullable ptr) {

stdlib/public/SwiftShims/swift/shims/RuntimeStubs.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_STDLIB_SHIMS_RUNTIMESTUBS_H_
2121

2222
#include "LibcShims.h"
23+
#include "Visibility.h"
2324

2425
#ifdef __cplusplus
2526
extern "C" {
@@ -31,6 +32,25 @@ SWIFT_RUNTIME_STDLIB_API
3132
__swift_ssize_t
3233
swift_stdlib_readLine_stdin(unsigned char * _Nullable * _Nonnull LinePtr);
3334

35+
// Pick a return-address strategy
36+
#if defined(__wasm__)
37+
// Wasm can't access call frame for security purposes
38+
#define get_return_address() ((void*) 0)
39+
#elif __GNUC__
40+
#define get_return_address() __builtin_return_address(0)
41+
#elif _MSC_VER
42+
#include <intrin.h>
43+
#define get_return_address() _ReturnAddress()
44+
#else
45+
#error missing implementation for get_return_address
46+
#define get_return_address() ((void*) 0)
47+
#endif
48+
49+
SWIFT_ALWAYS_INLINE
50+
static inline const void *_Nullable _swift_stdlib_get_return_address() {
51+
return get_return_address();
52+
}
53+
3454
SWIFT_END_NULLABILITY_ANNOTATIONS
3555

3656
#ifdef __cplusplus

stdlib/public/SwiftShims/swift/shims/ThreadLocalStorage.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,48 @@
1818
SWIFT_RUNTIME_STDLIB_INTERNAL
1919
void * _Nonnull _swift_stdlib_threadLocalStorageGet(void);
2020

21+
SWIFT_RUNTIME_STDLIB_INTERNAL
22+
void * _Nullable _swift_getExclusivityTLSImpl();
23+
24+
SWIFT_RUNTIME_STDLIB_INTERNAL
25+
void _swift_setExclusivityTLSImpl(void * _Nullable newValue);
26+
27+
#if defined(__APPLE__) && __arm64__
28+
29+
// Use a fast path on Apple ARM64, where we have a dedicated TLS key and fast
30+
// access to read/write it.
31+
32+
#ifndef __PTK_FRAMEWORK_SWIFT_KEY7
33+
# define __PTK_FRAMEWORK_SWIFT_KEY7 107
34+
#endif
35+
36+
#define SWIFT_RUNTIME_EXCLUSIVITY_KEY __PTK_FRAMEWORK_SWIFT_KEY7
37+
38+
static inline void * _Nullable * _Nonnull _swift_getExclusivityTLSPointer() {
39+
unsigned long tsd;
40+
__asm__ ("mrs %0, TPIDRRO_EL0" : "=r" (tsd));
41+
void **base = (void **)tsd;
42+
return &base[SWIFT_RUNTIME_EXCLUSIVITY_KEY];
43+
}
44+
45+
static inline void * _Nullable _swift_getExclusivityTLS() {
46+
return *_swift_getExclusivityTLSPointer();
47+
}
48+
49+
static inline void _swift_setExclusivityTLS(void * _Nullable newValue) {
50+
*_swift_getExclusivityTLSPointer() = newValue;
51+
}
52+
53+
#else
54+
55+
static inline void * _Nullable _swift_getExclusivityTLS() {
56+
return _swift_getExclusivityTLSImpl();
57+
}
58+
59+
static inline void _swift_setExclusivityTLS(void * _Nullable newValue) {
60+
_swift_setExclusivityTLSImpl(newValue);
61+
}
62+
63+
#endif
64+
2165
#endif // SWIFT_STDLIB_SHIMS_THREADLOCALSTORAGE_H

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ split_embedded_sources(
7878
EMBEDDED EnumeratedSequence.swift
7979
EMBEDDED Equatable.swift
8080
EMBEDDED ErrorType.swift
81+
NORMAL Exclusivity.swift
8182
EMBEDDED ExistentialCollection.swift
8283
EMBEDDED Filter.swift
8384
EMBEDDED FlatMap.swift

0 commit comments

Comments
 (0)