Skip to content

Commit f964b9f

Browse files
committed
[Threading] Don't use TLS keys as template arguments.
There's no guarantee that e.g. pthread_key_t is an integral type. It could be some kind of struct, or some other thing that isn't valid as a template argument. rdar://90776105
1 parent fd9cb75 commit f964b9f

File tree

13 files changed

+123
-71
lines changed

13 files changed

+123
-71
lines changed

include/swift/Threading/Impl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#ifndef SWIFT_THREADING_IMPL_H
1919
#define SWIFT_THREADING_IMPL_H
2020

21+
#include "TLSKeys.h"
22+
2123
// Try to autodetect if we aren't told what to do
2224
#if !SWIFT_THREADING_NONE && !SWIFT_THREADING_DARWIN && \
2325
!SWIFT_THREADING_LINUX && !SWIFT_THREADING_PTHREADS && \

include/swift/Threading/Impl/C11.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,16 @@ inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
164164
#define SWIFT_THREAD_LOCAL thread_local
165165
#endif
166166

167-
using tls_key = ::tss_t;
168-
using tls_dtor = void (*)(void *);
167+
using tls_key_t = ::tss_t;
168+
using tls_dtor_t = void (*)(void *);
169169

170-
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
170+
inline bool tls_alloc(tls_key_t &key, tls_dtor_t dtor) {
171171
return ::tss_create(&key, dtor) == thrd_success;
172172
}
173173

174-
inline void *tls_get(tls_key key) { return ::tss_get(key); }
174+
inline void *tls_get(tls_key_t key) { return ::tss_get(key); }
175175

176-
inline void tls_set(tls_key key, void *ptr) { ::tss_set(key, ptr); }
176+
inline void tls_set(tls_key_t key, void *ptr) { ::tss_set(key, ptr); }
177177

178178
} // namespace threading_impl
179179

include/swift/Threading/Impl/Darwin.h

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,45 +128,60 @@ inline void _pthread_setspecific_direct(pthread_key_t k, void *v) {
128128
}
129129
#endif
130130

131-
#define SWIFT_RUNTIME_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY0
132-
#define SWIFT_STDLIB_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY1
133-
#define SWIFT_COMPATIBILITY_50_TLS_KEY __PTK_FRAMEWORK_SWIFT_KEY2
134-
#define SWIFT_CONCURRENCY_TASK_KEY __PTK_FRAMEWORK_SWIFT_KEY3
135-
#define SWIFT_CONCURRENCY_EXECUTOR_TRACKING_INFO_KEY __PTK_FRAMEWORK_SWIFT_KEY4
136-
#define SWIFT_CONCURRENCY_FALLBACK_TASK_LOCAL_STORAGE_KEY \
137-
__PTK_FRAMEWORK_SWIFT_KEY5
138-
#define SWIFT_RESERVED_TLS_KEY_6 __PTK_FRAMEWORK_SWIFT_KEY6
139-
#define SWIFT_RESERVED_TLS_KEY_7 __PTK_FRAMEWORK_SWIFT_KEY7
140-
#define SWIFT_RESERVED_TLS_KEY_8 __PTK_FRAMEWORK_SWIFT_KEY8
141-
#define SWIFT_RESERVED_TLS_KEY_9 __PTK_FRAMEWORK_SWIFT_KEY9
142-
143131
#define SWIFT_TLS_DECLARE_DTOR(name) void name(void *)
144132

145-
using tls_key = pthread_key_t;
146-
using tls_dtor = void (*)(void *);
147-
148-
inline bool tls_init(tls_key key, tls_dtor dtor) {
133+
using tls_key_t = pthread_key_t;
134+
using tls_dtor_t = void (*)(void *);
135+
136+
inline tls_key_t tls_get_key(tls_key k) {
137+
switch (k) {
138+
case tls_key::runtime:
139+
return __PTK_FRAMEWORK_SWIFT_KEY0;
140+
case tls_key::stdlib:
141+
return __PTK_FRAMEWORK_SWIFT_KEY1;
142+
case tls_key::compatibility50:
143+
return __PTK_FRAMEWORK_SWIFT_KEY2;
144+
case tls_key::concurrency_task:
145+
return __PTK_FRAMEWORK_SWIFT_KEY3;
146+
case tls_key::concurrency_executor_tracking_info:
147+
return __PTK_FRAMEWORK_SWIFT_KEY4;
148+
case tls_key::concurrency_fallback:
149+
return __PTK_FRAMEWORK_SWIFT_KEY5;
150+
}
151+
}
152+
153+
inline bool tls_init(tls_key_t key, tls_dtor_t dtor) {
149154
return pthread_key_init_np(key, dtor) == 0;
150155
}
151156

152-
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
157+
inline bool tls_init(tls_key key, tls_dtor_t dtor) {
158+
return tls_init(tls_get_key(key), dtor);
159+
}
160+
161+
inline bool tls_alloc(tls_key_t &key, tls_dtor_t dtor) {
153162
return pthread_key_create(&key, dtor) == 0;
154163
}
155164

156-
inline void *tls_get(tls_key key) {
165+
inline void *tls_get(tls_key_t key) {
157166
if (_pthread_has_direct_tsd())
158167
return _pthread_getspecific_direct(key);
159168
else
160169
return pthread_getspecific(key);
161170
}
162171

163-
inline void tls_set(tls_key key, void *value) {
172+
inline void *tls_get(tls_key key) { return tls_get(tls_get_key(key)); }
173+
174+
inline void tls_set(tls_key_t key, void *value) {
164175
if (_pthread_has_direct_tsd())
165176
_pthread_setspecific_direct(key, value);
166177
else
167178
pthread_setspecific(key, value);
168179
}
169180

181+
inline void tls_set(tls_key key, void *value) {
182+
tls_set(tls_get_key(key), value);
183+
}
184+
170185
} // namespace threading_impl
171186

172187
} // namespace swift

include/swift/Threading/Impl/Linux.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,16 +149,16 @@ inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
149149
#define SWIFT_THREAD_LOCAL thread_local
150150
#endif
151151

152-
using tls_key = pthread_key_t;
153-
using tls_dtor = void (*)(void *);
152+
using tls_key_t = pthread_key_t;
153+
using tls_dtor_t = void (*)(void *);
154154

155-
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
155+
inline bool tls_alloc(tls_key_t &key, tls_dtor_t dtor) {
156156
return pthread_key_create(&key, dtor) == 0;
157157
}
158158

159-
inline void *tls_get(tls_key key) { return pthread_getspecific(key); }
159+
inline void *tls_get(tls_key_t key) { return pthread_getspecific(key); }
160160

161-
inline void tls_set(tls_key key, void *value) {
161+
inline void tls_set(tls_key_t key, void *value) {
162162
pthread_setspecific(key, value);
163163
}
164164

include/swift/Threading/Impl/Pthreads.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,16 @@ inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
145145
#define SWIFT_THREAD_LOCAL thread_local
146146
#endif
147147

148-
using tls_key = pthread_key_t;
149-
using tls_dtor = void (*)(void *);
148+
using tls_key_t = pthread_key_t;
149+
using tls_dtor_t = void (*)(void *);
150150

151-
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
151+
inline bool tls_alloc(tls_key_t &key, tls_dtor_t dtor) {
152152
return pthread_key_create(&key, dtor) == 0;
153153
}
154154

155-
inline void *tls_get(tls_key key) { return pthread_getspecific(key); }
155+
inline void *tls_get(tls_key_t key) { return pthread_getspecific(key); }
156156

157-
inline void tls_set(tls_key key, void *value) {
157+
inline void tls_set(tls_key_t key, void *value) {
158158
pthread_setspecific(key, value);
159159
}
160160

include/swift/Threading/Impl/Win32.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,17 @@ inline void once_impl(once_t &predicate, void (*fn)(void *), void *context) {
109109

110110
#define SWIFT_TLS_DECLARE_DTOR(name) void NTAPI name(void *)
111111

112-
using tls_key = ::DWORD;
113-
using tls_dtor = ::PFLS_CALLBACK_FUNCTION;
112+
using tls_key_t = ::DWORD;
113+
using tls_dtor_t = ::PFLS_CALLBACK_FUNCTION;
114114

115-
inline bool tls_alloc(tls_key &key, tls_dtor dtor) {
115+
inline bool tls_alloc(tls_key_t &key, tls_dtor_t dtor) {
116116
key = ::FlsAlloc(dtor);
117117
return key != FLS_OUT_OF_INDEXES;
118118
}
119119

120-
inline void *tls_get(tls_key key) { return ::FlsGetValue(key); }
120+
inline void *tls_get(tls_key_t key) { return ::FlsGetValue(key); }
121121

122-
inline void tls_set(tls_key key, void *value) { ::FlsSetValue(key, value); }
122+
inline void tls_set(tls_key_t key, void *value) { ::FlsSetValue(key, value); }
123123

124124
} // namespace threading_impl
125125

include/swift/Threading/TLSKeys.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--- TLSKeys.h - Reserved TLS keys ------------------------ -*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 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+
#ifndef SWIFT_THREADING_TLSKEYS_H
14+
#define SWIFT_THREADING_TLSKEYS_H
15+
16+
namespace swift {
17+
18+
enum class tls_key {
19+
runtime,
20+
stdlib,
21+
compatibility50,
22+
concurrency_task,
23+
concurrency_executor_tracking_info,
24+
concurrency_fallback
25+
};
26+
27+
} // namespace swift
28+
29+
#endif // SWIFT_THREADING_TLSKEYS_H

include/swift/Threading/ThreadLocalStorage.h

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//===--- ThreadLocalStorage.h - Thread-local storage interface. --*- C++
2-
//-*-===//
1+
//===--- ThreadLocalStorage.h - Thread-local storage interface. -*- C++ -*-===//
32
//
43
// This source file is part of the Swift.org open source project
54
//
@@ -19,23 +18,25 @@
1918
#include "Errors.h"
2019
#include "Impl.h"
2120
#include "Once.h"
21+
#include "TLSKeys.h"
2222

2323
namespace swift {
2424

2525
// -- Low-level TLS functions -------------------------------------------------
2626

2727
#if !SWIFT_THREADING_NONE
28-
using tls_key = threading_impl::tls_key;
29-
using tls_dtor = threading_impl::tls_dtor;
28+
using tls_key_t = threading_impl::tls_key_t;
29+
using tls_dtor_t = threading_impl::tls_dtor_t;
3030

3131
#if SWIFT_THREADING_USE_RESERVED_TLS_KEYS
32+
using threading_impl::tls_get_key;
3233
using threading_impl::tls_init;
3334

3435
/// tls_init_once() - Initialize TLS, once only
35-
inline void tls_init_once(once_t &token, tls_key key, tls_dtor dtor) {
36+
inline void tls_init_once(once_t &token, tls_key_t key, tls_dtor_t dtor) {
3637
const struct tls_init_info {
37-
tls_key &k;
38-
tls_dtor d;
38+
tls_key_t &k;
39+
tls_dtor_t d;
3940
} info = {key, dtor};
4041
once(
4142
token,
@@ -47,17 +48,21 @@ inline void tls_init_once(once_t &token, tls_key key, tls_dtor dtor) {
4748
},
4849
(void *)&info);
4950
}
51+
52+
inline void tls_init_once(once_t &token, tls_key key, tls_dtor_t dtor) {
53+
tls_init_once(token, tls_get_key(key), dtor);
54+
}
5055
#endif // SWIFT_THREADING_USE_RESERVED_TLS_KEYS
5156

5257
using threading_impl::tls_alloc;
5358
using threading_impl::tls_get;
5459
using threading_impl::tls_set;
5560

5661
/// tls_alloc_once() - Allocate TLS key, once only
57-
inline void tls_alloc_once(once_t &token, tls_key &key, tls_dtor dtor) {
62+
inline void tls_alloc_once(once_t &token, tls_key_t &key, tls_dtor_t dtor) {
5863
const struct tls_init_info {
59-
tls_key &k;
60-
tls_dtor d;
64+
tls_key_t &k;
65+
tls_dtor_t d;
6166
} info = {key, dtor};
6267
once(
6368
token,
@@ -117,28 +122,30 @@ class ThreadLocalKey {
117122
// We rely on the zero-initialization of objects with static storage
118123
// duration.
119124
once_t onceFlag;
120-
tls_key key;
125+
tls_key_t key;
121126

122127
public:
123-
threading_impl::tls_key getKey() {
128+
threading_impl::tls_key_t getKey() {
124129
once(
125130
onceFlag,
126131
[](void *ctx) {
127-
tls_key *pkey = reinterpret_cast<tls_key *>(ctx);
132+
tls_key_t *pkey = reinterpret_cast<tls_key_t *>(ctx);
128133
tls_alloc(*pkey, nullptr);
129134
},
130135
&key);
131136
return key;
132137
}
133138
};
134139

140+
#if SWIFT_THREADING_USE_RESERVED_TLS_KEYS
135141
// A type representing a constant TLS key, for use on platforms
136142
// that provide reserved keys.
137143
template <tls_key constantKey>
138144
class ConstantThreadLocalKey {
139145
public:
140-
tls_key getKey() { return constantKey; }
146+
tls_key_t getKey() { return tls_get_key(constantKey); }
141147
};
148+
#endif
142149

143150
template <class T, class Key>
144151
class ThreadLocal {
@@ -172,7 +179,7 @@ class ThreadLocal {
172179
///
173180
/// For example
174181
///
175-
/// static SWIFT_THREAD_LOCAL_TYPE(int, SWIFT_RESERVED_TLS_KEY_9) frobble;
182+
/// static SWIFT_THREAD_LOCAL_TYPE(int, SWIFT_RESERVED_TLS_KEY_T_9) frobble;
176183
///
177184
/// Because of the fallback path, the default-initialization of the
178185
/// type must be equivalent to a bitwise zero-initialization, and the

stdlib/public/Concurrency/Actor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class ExecutorTrackingInfo {
108108
/// separate thread-local variable (or whatever is most efficient
109109
/// on the target platform).
110110
static SWIFT_THREAD_LOCAL_TYPE(Pointer<ExecutorTrackingInfo>,
111-
SWIFT_CONCURRENCY_EXECUTOR_TRACKING_INFO_KEY)
111+
tls_key::concurrency_executor_tracking_info)
112112
ActiveInfoInThread;
113113

114114
/// The active executor.
@@ -176,19 +176,19 @@ class ActiveTask {
176176
/// A thread-local variable pointing to the active tracking
177177
/// information about the current thread, if any.
178178
static SWIFT_THREAD_LOCAL_TYPE(Pointer<AsyncTask>,
179-
SWIFT_CONCURRENCY_TASK_KEY) Value;
179+
tls_key::concurrency_task) Value;
180180

181181
public:
182182
static void set(AsyncTask *task) { Value.set(task); }
183183
static AsyncTask *get() { return Value.get(); }
184184
};
185185

186186
/// Define the thread-locals.
187-
SWIFT_THREAD_LOCAL_TYPE(Pointer<AsyncTask>, SWIFT_CONCURRENCY_TASK_KEY)
187+
SWIFT_THREAD_LOCAL_TYPE(Pointer<AsyncTask>, tls_key::concurrency_task)
188188
ActiveTask::Value;
189189

190190
SWIFT_THREAD_LOCAL_TYPE(Pointer<ExecutorTrackingInfo>,
191-
SWIFT_CONCURRENCY_EXECUTOR_TRACKING_INFO_KEY)
191+
tls_key::concurrency_executor_tracking_info)
192192
ExecutorTrackingInfo::ActiveInfoInThread;
193193

194194
} // end anonymous namespace

stdlib/public/Concurrency/TaskLocal.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ template <class T> struct Pointer {
5454

5555
/// THIS IS RUNTIME INTERNAL AND NOT ABI.
5656
class FallbackTaskLocalStorage {
57-
static SWIFT_THREAD_LOCAL_TYPE(
58-
Pointer<TaskLocal::Storage>,
59-
SWIFT_CONCURRENCY_FALLBACK_TASK_LOCAL_STORAGE_KEY) Value;
57+
static SWIFT_THREAD_LOCAL_TYPE(Pointer<TaskLocal::Storage>,
58+
tls_key::concurrency_fallback) Value;
6059

6160
public:
6261
static void set(TaskLocal::Storage *task) { Value.set(task); }
@@ -65,7 +64,7 @@ class FallbackTaskLocalStorage {
6564

6665
/// Define the thread-locals.
6766
SWIFT_THREAD_LOCAL_TYPE(Pointer<TaskLocal::Storage>,
68-
SWIFT_CONCURRENCY_FALLBACK_TASK_LOCAL_STORAGE_KEY)
67+
tls_key::concurrency_fallback)
6968
FallbackTaskLocalStorage::Value;
7069

7170
// ==== ABI --------------------------------------------------------------------

stdlib/public/runtime/SwiftTLSContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ SwiftTLSContext &SwiftTLSContext::get() {
2424

2525
// If we have reserved keys, use those
2626
SwiftTLSContext *ctx =
27-
static_cast<SwiftTLSContext *>(swift::tls_get(SWIFT_RUNTIME_TLS_KEY));
27+
static_cast<SwiftTLSContext *>(swift::tls_get(swift::tls_key::runtime));
2828
if (ctx)
2929
return *ctx;
3030

3131
static swift::once_t token;
32-
swift::tls_init_once(token, SWIFT_RUNTIME_TLS_KEY, [](void *pointer) {
32+
swift::tls_init_once(token, swift::tls_key::runtime, [](void *pointer) {
3333
delete static_cast<SwiftTLSContext *>(pointer);
3434
});
3535

3636
ctx = new SwiftTLSContext();
37-
swift::tls_set(SWIFT_RUNTIME_TLS_KEY, ctx);
37+
swift::tls_set(swift::tls_key::runtime, ctx);
3838
return *ctx;
3939

4040
#elif defined(SWIFT_THREAD_LOCAL)
@@ -47,7 +47,7 @@ SwiftTLSContext &SwiftTLSContext::get() {
4747
#else
4848

4949
// Otherwise, allocate ourselves a key and use that
50-
static swift::tls_key runtimeKey;
50+
static swift::tls_key_t runtimeKey;
5151
static swift::once_t token;
5252

5353
swift::tls_alloc_once(token, runtimeKey, [](void *pointer) {

0 commit comments

Comments
 (0)