Skip to content

Commit aaa03f3

Browse files
committed
[Threading][TSan] Update after review comments.
* Use the longer name ThreadSanitizer rather than TSan for the new files. * Don't implement `tsan::consume` at all for now. * Do the `tsan::release` for `ulock_unlock()` at the head of the function, not at the tail. * Add a comment to test/Sanitizers/tsan/once.swift to explain the test a little more clearly. rdar://110665213
1 parent 85bb66c commit aaa03f3

File tree

8 files changed

+27
-31
lines changed

8 files changed

+27
-31
lines changed

include/swift/Threading/Impl/Linux/ulock.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include <atomic>
3535
#include <cstdint>
3636

37-
#include "swift/Threading/TSan.h"
37+
#include "swift/Threading/ThreadSanitizer.h"
3838

3939
namespace swift {
4040
namespace threading_impl {
@@ -84,6 +84,8 @@ inline bool ulock_trylock(ulock_t *lock) {
8484
}
8585

8686
inline void ulock_unlock(ulock_t *lock) {
87+
tsan::release(lock);
88+
8789
const ulock_t tid = ulock_get_tid();
8890
do {
8991
ulock_t expected = tid;
@@ -92,8 +94,6 @@ inline void ulock_unlock(ulock_t *lock) {
9294
__ATOMIC_RELAXED)))
9395
break;
9496
} while (ulock_futex(lock, FUTEX_UNLOCK_PI) != 0);
95-
96-
tsan::release(lock);
9797
}
9898

9999
} // namespace linux

include/swift/Threading/TSan.h renamed to include/swift/Threading/ThreadSanitizer.h

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- TSan.h - TSan support functions ---------------------- -*- C++ -*-===//
1+
//===--- ThreadSanitizer.h - Thread Sanitizer support --------- -*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -17,8 +17,8 @@
1717
//
1818
//===----------------------------------------------------------------------===//
1919

20-
#ifndef SWIFT_THREADING_TSAN_H
21-
#define SWIFT_THREADING_TSAN_H
20+
#ifndef SWIFT_THREADING_THREAD_SANITIZER_H
21+
#define SWIFT_THREADING_THREAD_SANITIZER_H
2222

2323
namespace swift {
2424

@@ -28,7 +28,6 @@ namespace tsan {
2828
inline bool enabled() { return false; }
2929
template <typename T> T *acquire(T *ptr) { return ptr; }
3030
template <typename T> T *release(T *ptr) { return ptr; }
31-
template <typename T> T *consume(T *ptr) { return ptr; }
3231

3332
} // namespace tsan
3433
#else
@@ -73,19 +72,6 @@ T *release(T *ptr) {
7372
return ptr;
7473
}
7574

76-
/// Indicate to TSan that a consuming load has occurred on the current
77-
/// thread. If some other thread does a releasing store with the same
78-
/// pointer, we are indicating to TSan that all writes that happened
79-
/// before that store will be visible *to those operations that carry a
80-
/// dependency on the loaded value*.
81-
///
82-
/// TSan doesn't currently know about consume, so we lie and say it's an
83-
/// acquire instead.
84-
template <typename T>
85-
T *consume(T *ptr) {
86-
return acquire(ptr);
87-
}
88-
8975
} // namespace tsan
9076

9177
#endif

lib/Threading/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ add_swift_host_library(swiftThreading STATIC
1111
Pthreads.cpp
1212
Win32.cpp
1313
Errors.cpp
14-
TSan.cpp)
14+
ThreadSanitizer.cpp)

lib/Threading/Linux.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
#include "swift/Threading/Impl.h"
2020
#include "swift/Threading/Errors.h"
21-
#include "swift/Threading/TSan.h"
21+
#include "swift/Threading/ThreadSanitizer.h"
2222

2323
namespace {
2424

lib/Threading/TSan.cpp renamed to lib/Threading/ThreadSanitizer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- TSan.h - TSan support functions ----------------------------------===//
1+
//===--- ThreadSanitizer.cpp - Thread Sanitizer support -------------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -17,7 +17,7 @@
1717
//
1818
//===----------------------------------------------------------------------===//
1919

20-
#include "swift/Threading/TSan.h"
20+
#include "swift/Threading/ThreadSanitizer.h"
2121
#include "swift/shims/Visibility.h"
2222

2323
namespace swift {

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "swift/Runtime/Exclusivity.h"
3030
#include "swift/Runtime/HeapObject.h"
3131
#include "swift/Threading/Thread.h"
32-
#include "swift/Threading/TSan.h"
32+
#include "swift/Threading/ThreadSanitizer.h"
3333
#include <atomic>
3434
#include <new>
3535

@@ -100,17 +100,22 @@ void _swift_taskGroup_cancelAllChildren(TaskGroup *group);
100100
/// should generally use a higher-level function.
101101
void _swift_taskGroup_detachChild(TaskGroup *group, AsyncTask *child);
102102

103-
/// Tell TSAN about an acquiring load
103+
/// Tell TSan about an acquiring load
104104
inline void _swift_tsan_acquire(void *addr) {
105105
swift::tsan::acquire(addr);
106106
}
107-
/// Tell TSAN about a releasing store
107+
/// Tell TSan about a releasing store
108108
inline void _swift_tsan_release(void *addr) {
109109
swift::tsan::release(addr);
110110
}
111-
/// Tell TSAN about a consuming load
111+
/// Tell TSan about a consuming load
112112
inline void _swift_tsan_consume(void *addr) {
113-
swift::tsan::consume(addr);
113+
// TSan doesn't support consume, so pretend it's an acquire.
114+
//
115+
// Note that that means that TSan won't generate errors for non-dependent
116+
// reads, so this isn't entirely safe if you're relying solely on TSan to
117+
// spot bugs.
118+
swift::tsan::acquire(addr);
114119
}
115120

116121
/// Special values used with DispatchQueueIndex to indicate the global and main

stdlib/public/Threading/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ add_swift_target_library(swiftThreading OBJECT_LIBRARY
99
"${SWIFT_SOURCE_DIR}/lib/Threading/Linux.cpp"
1010
"${SWIFT_SOURCE_DIR}/lib/Threading/Pthreads.cpp"
1111
"${SWIFT_SOURCE_DIR}/lib/Threading/Win32.cpp"
12-
"${SWIFT_SOURCE_DIR}/lib/Threading/TSan.cpp"
12+
"${SWIFT_SOURCE_DIR}/lib/Threading/ThreadSanitizer.cpp"
1313
INSTALL_IN_COMPONENT never_install)

test/Sanitizers/tsan/once.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@
1212
// UNSUPPORTED: remote_run
1313

1414
// Test that we do not report a race on initialization; Swift doesn't initialize
15-
// globals at start-up, but rather uses swift_once(). This is thread safe, but
15+
// globals at start-up, but rather uses `swift_once()`. This is thread safe, but
1616
// on some platforms TSan wasn't seeing the synchronization, so would report
1717
// a false positive.
1818

1919
import Dispatch
2020

2121
var count = 0
22+
23+
// This initialization will be done via a call to `swift_once()`. Prior to
24+
// the fix for rdar://110665213, the addition to `count` would trigger a
25+
// TSan message on Linux because the sanitizer couldn't see the lock we're
26+
// using to make `swift_once()` thread safe.
2227
let foo = {
2328
count += 1
2429
return count

0 commit comments

Comments
 (0)