Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,23 +170,23 @@ TEST(TestRtsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) {
ExpectNonRealtimeSurvival(Func);
}

TEST(TestRtsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
std::atomic<float> small_atomic{0.0f};
ASSERT_TRUE(small_atomic.is_lock_free());
RealtimeInvoke([&small_atomic]() {
float x = small_atomic.load();
return x;
});

std::atomic<std::array<float, 2048>> large_atomic;
ASSERT_FALSE(large_atomic.is_lock_free());
auto Func = [&]() {
std::array<float, 2048> x = large_atomic.load();
return x;
};
ExpectRealtimeDeath(Func);
ExpectNonRealtimeSurvival(Func);
}
// TEST(TestRtsan, AccessingALargeAtomicVariableDiesWhenRealtime) {
// std::atomic<float> small_atomic{0.0f};
// ASSERT_TRUE(small_atomic.is_lock_free());
// RealtimeInvoke([&small_atomic]() {
// float x = small_atomic.load();
// return x;
// });

// std::atomic<std::array<float, 2048>> large_atomic;
// ASSERT_FALSE(large_atomic.is_lock_free());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To explain what is going on here (just being explicit so you have as much info as possible, you may know any/all of this).

Small types which are made atomics don't need locks, they rely on arch specific instructions. Luckily for us real-time programmers, C++ standard added the .is_lock_free assertion so we could sanity check ourselves before using these in timing critical code.

The first half of these test determines that a basic float may be used atomically without an underlying lock happening, we don't intercept anything and don't die.

The second half test uses a mega 2048 float buffer, which cannot be atomically updated without a lock (on any arch I know of). We then test that we intercept the lock call that happens implicitly under the hood. On my mac this intercepts a pthread_mutex_lock I believe.

This passes on my mac, at least, but perhaps Apple changed the internal implementation of the STL to use a different type of lock we don't currently intercept? That fix would be easy enough to do, we could just add the new call into our interceptors.

If you have found some way to make an atomic update of 2048 floats at once with NO LOCKS, please share the secret sauce 👀

// auto Func = [&]() {
// std::array<float, 2048> x = large_atomic.load();
// return x;
// };
// ExpectRealtimeDeath(Func);
// ExpectNonRealtimeSurvival(Func);
// }

TEST(TestRtsan, FirstCoutDiesWhenRealtime) {
auto Func = []() { std::cout << "Hello, world!" << std::endl; };
Expand Down
24 changes: 12 additions & 12 deletions compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1037,18 +1037,18 @@ TEST(TestRtsanInterceptors, PthreadJoinDiesWhenRealtime) {

#if SANITIZER_APPLE

#pragma clang diagnostic push
// OSSpinLockLock is deprecated, but still in use in libc++
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
auto Func = []() {
OSSpinLock spin_lock{};
OSSpinLockLock(&spin_lock);
};
ExpectRealtimeDeath(Func, "OSSpinLockLock");
ExpectNonRealtimeSurvival(Func);
}
#pragma clang diagnostic pop
// #pragma clang diagnostic push
// // OSSpinLockLock is deprecated, but still in use in libc++
// #pragma clang diagnostic ignored "-Wdeprecated-declarations"
// TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this test, is it possible that your internal build of MacOS completely killed off OsSpinLock, and this call no longer does anything? That's my very naive hunch seeing as it's wrapped in in -Wno-deprecated-declarations

Copy link
Contributor Author

@thetruestblue thetruestblue Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think I have an explanation for this one. The locks were changed to macros that point to other locking mechanisms
See: a34159f

// auto Func = []() {
// OSSpinLock spin_lock{};
// OSSpinLockLock(&spin_lock);
// };
// ExpectRealtimeDeath(Func, "OSSpinLockLock");
// ExpectNonRealtimeSurvival(Func);
// }
// #pragma clang diagnostic pop

TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) {
auto Func = []() {
Expand Down