Skip to content

Commit 99bcd87

Browse files
author
Julian Lettner
committed
Use swift_once instead of C++ static initializers
1 parent 58056ff commit 99bcd87

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

stdlib/public/Concurrency/Task.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,6 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
9292
using Status = FutureFragment::Status;
9393
using WaitQueueItem = FutureFragment::WaitQueueItem;
9494

95-
_swift_tsan_release(static_cast<Job *>(this));
96-
9795
assert(isFuture());
9896
auto fragment = futureFragment();
9997

@@ -105,6 +103,8 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
105103
hadErrorResult = true;
106104
}
107105

106+
_swift_tsan_release(static_cast<Job *>(this));
107+
108108
// Update the status to signal completion.
109109
auto newQueueHead = WaitQueueItem::get(
110110
hadErrorResult ? Status::Error : Status::Success,
@@ -125,8 +125,6 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
125125
// Schedule every waiting task on the executor.
126126
auto waitingTask = queueHead.getTask();
127127
while (waitingTask) {
128-
_swift_tsan_acquire(static_cast<Job *>(waitingTask));
129-
130128
// Find the next waiting task before we invalidate it by resuming
131129
// the task.
132130
auto nextWaitingTask = waitingTask->getNextWaitingTask();
@@ -140,6 +138,8 @@ void AsyncTask::completeFuture(AsyncContext *context, ExecutorRef executor) {
140138
waitingContext->fillWithSuccess(fragment);
141139
}
142140

141+
_swift_tsan_acquire(static_cast<Job *>(waitingTask));
142+
143143
// Enqueue the waiter on the global executor.
144144
// TODO: allow waiters to fill in a suggested executor
145145
swift_task_enqueueGlobal(waitingTask);

stdlib/public/Concurrency/ThreadSanitizer.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,35 @@
2323
#include <dlfcn.h>
2424
#endif
2525

26+
namespace {
2627
using TSanFunc = void(void *);
28+
TSanFunc *tsan_acquire, *tsan_release;
2729

28-
namespace {
29-
static TSanFunc *loadSymbol(const char *name) {
30+
TSanFunc *loadSymbol(const char *name) {
3031
#if defined(_WIN32)
3132
return (TSanFunc *)GetProcAddress(GetModuleHandle(NULL), name);
3233
#else
3334
return (TSanFunc *)dlsym(RTLD_DEFAULT, name);
3435
#endif
3536
}
37+
38+
swift::swift_once_t initOnceToken;
39+
void initializeThreadSanitizer(void *unused) {
40+
tsan_acquire = loadSymbol("__tsan_acquire");
41+
tsan_release = loadSymbol("__tsan_release");
3642
}
43+
} // anonymous namespace
3744

3845
void swift::_swift_tsan_acquire(void *addr) {
39-
static auto ptr = loadSymbol("__tsan_acquire");
40-
if (ptr) {
41-
ptr(addr);
46+
swift_once(&initOnceToken, initializeThreadSanitizer, nullptr);
47+
if (tsan_acquire) {
48+
tsan_acquire(addr);
4249
}
4350
}
4451

4552
void swift::_swift_tsan_release(void *addr) {
46-
static auto ptr = loadSymbol("__tsan_release");
47-
if (ptr) {
48-
ptr(addr);
53+
swift_once(&initOnceToken, initializeThreadSanitizer, nullptr);
54+
if (tsan_release) {
55+
tsan_release(addr);
4956
}
5057
}

0 commit comments

Comments
 (0)