[compiler-rt] 5ed03c1 - [sanitizer] Simplify sanitizer_stoptheworld_test
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 16 23:28:21 PST 2021
Author: Vitaly Buka
Date: 2021-12-16T23:24:17-08:00
New Revision: 5ed03c1e1025a0fee23c294a8e92f3f9e54833dd
URL: https://github.com/llvm/llvm-project/commit/5ed03c1e1025a0fee23c294a8e92f3f9e54833dd
DIFF: https://github.com/llvm/llvm-project/commit/5ed03c1e1025a0fee23c294a8e92f3f9e54833dd.diff
LOG: [sanitizer] Simplify sanitizer_stoptheworld_test
Added:
Modified:
compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
index 07a3192c0474d..247d161de0b76 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
@@ -15,6 +15,7 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_LINUX && defined(__x86_64__)
+# include <atomic>
# include <mutex>
# include <thread>
@@ -24,22 +25,20 @@
namespace __sanitizer {
-static std::mutex incrementer_thread_exit_mutex;
+static std::mutex mutex;
struct CallbackArgument {
- volatile int counter;
- volatile bool threads_stopped;
- volatile bool callback_executed;
- CallbackArgument()
- : counter(0), threads_stopped(false), callback_executed(false) {}
+ std::atomic_int counter = {};
+ std::atomic_bool threads_stopped = {};
+ std::atomic_bool callback_executed = {};
};
void IncrementerThread(CallbackArgument &callback_argument) {
while (true) {
- __sync_fetch_and_add(&callback_argument.counter, 1);
+ callback_argument.counter++;
- if (incrementer_thread_exit_mutex.try_lock()) {
- incrementer_thread_exit_mutex.unlock();
+ if (mutex.try_lock()) {
+ mutex.unlock();
return;
}
@@ -53,11 +52,10 @@ void Callback(const SuspendedThreadsList &suspended_threads_list,
void *argument) {
CallbackArgument *callback_argument = (CallbackArgument *)argument;
callback_argument->callback_executed = true;
- int counter_at_init = __sync_fetch_and_add(&callback_argument->counter, 0);
+ int counter_at_init = callback_argument->counter;
for (uptr i = 0; i < 1000; i++) {
std::this_thread::yield();
- if (__sync_fetch_and_add(&callback_argument->counter, 0) !=
- counter_at_init) {
+ if (callback_argument->counter != counter_at_init) {
callback_argument->threads_stopped = false;
return;
}
@@ -68,10 +66,11 @@ void Callback(const SuspendedThreadsList &suspended_threads_list,
TEST(StopTheWorld, SuspendThreadsSimple) {
CallbackArgument argument;
std::thread thread;
- incrementer_thread_exit_mutex.lock();
- ASSERT_NO_THROW(thread = std::thread(IncrementerThread, std::ref(argument)));
- StopTheWorld(&Callback, &argument);
- incrementer_thread_exit_mutex.unlock();
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ thread = std::thread(IncrementerThread, std::ref(argument));
+ StopTheWorld(&Callback, &argument);
+ }
EXPECT_TRUE(argument.callback_executed);
EXPECT_TRUE(argument.threads_stopped);
// argument is on stack, so we have to wait for the incrementer thread to
@@ -84,43 +83,26 @@ TEST(StopTheWorld, SuspendThreadsSimple) {
static const uptr kThreadCount = 50;
static const uptr kStopWorldAfter = 10; // let this many threads spawn first
-static std::mutex advanced_incrementer_thread_exit_mutex;
-
struct AdvancedCallbackArgument {
- volatile uptr thread_index;
- volatile int counters[kThreadCount];
+ std::atomic_uintptr_t thread_index = {};
+ std::atomic_int counters[kThreadCount] = {};
std::thread threads[kThreadCount];
- volatile bool threads_stopped;
- volatile bool callback_executed;
- volatile bool fatal_error;
- AdvancedCallbackArgument()
- : thread_index(0),
- threads_stopped(false),
- callback_executed(false),
- fatal_error(false) {}
+ std::atomic_bool threads_stopped = {};
+ std::atomic_bool callback_executed = {};
};
void AdvancedIncrementerThread(AdvancedCallbackArgument &callback_argument) {
- uptr this_thread_index =
- __sync_fetch_and_add(&callback_argument.thread_index, 1);
+ uptr this_thread_index = callback_argument.thread_index++;
// Spawn the next thread.
if (this_thread_index + 1 < kThreadCount) {
- try {
- callback_argument.threads[this_thread_index + 1] =
- std::thread(AdvancedIncrementerThread, std::ref(callback_argument));
- } catch (...) {
- // Cannot use ASSERT_EQ in non-void-returning functions. If there's a
- // problem, defer failing to the main thread.
- callback_argument.fatal_error = true;
- __sync_fetch_and_add(&callback_argument.thread_index,
- kThreadCount - callback_argument.thread_index);
- }
+ callback_argument.threads[this_thread_index + 1] =
+ std::thread(AdvancedIncrementerThread, std::ref(callback_argument));
}
// Do the actual work.
while (true) {
- __sync_fetch_and_add(&callback_argument.counters[this_thread_index], 1);
- if (advanced_incrementer_thread_exit_mutex.try_lock()) {
- advanced_incrementer_thread_exit_mutex.unlock();
+ callback_argument.counters[this_thread_index]++;
+ if (mutex.try_lock()) {
+ mutex.unlock();
return;
}
@@ -136,13 +118,11 @@ void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
int counters_at_init[kThreadCount];
for (uptr j = 0; j < kThreadCount; j++)
- counters_at_init[j] =
- __sync_fetch_and_add(&callback_argument->counters[j], 0);
+ counters_at_init[j] = callback_argument->counters[j];
for (uptr i = 0; i < 10; i++) {
std::this_thread::yield();
for (uptr j = 0; j < kThreadCount; j++)
- if (__sync_fetch_and_add(&callback_argument->counters[j], 0) !=
- counters_at_init[j]) {
+ if (callback_argument->counters[j] != counters_at_init[j]) {
callback_argument->threads_stopped = false;
return;
}
@@ -153,23 +133,21 @@ void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
TEST(StopTheWorld, SuspendThreadsAdvanced) {
AdvancedCallbackArgument argument;
- advanced_incrementer_thread_exit_mutex.lock();
- argument.threads[0] =
- std::thread(AdvancedIncrementerThread, std::ref(argument));
- // Wait for several threads to spawn before proceeding.
- while (__sync_fetch_and_add(&argument.thread_index, 0) < kStopWorldAfter)
- std::this_thread::yield();
- StopTheWorld(&AdvancedCallback, &argument);
- EXPECT_TRUE(argument.callback_executed);
- EXPECT_TRUE(argument.threads_stopped);
-
- // Wait for all threads to spawn before we start terminating them.
- while (__sync_fetch_and_add(&argument.thread_index, 0) < kThreadCount)
- std::this_thread::yield();
- ASSERT_FALSE(argument.fatal_error); // a thread could not be started
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ argument.threads[0] =
+ std::thread(AdvancedIncrementerThread, std::ref(argument));
+ // Wait for several threads to spawn before proceeding.
+ while (argument.thread_index < kStopWorldAfter) std::this_thread::yield();
+ StopTheWorld(&AdvancedCallback, &argument);
+ EXPECT_TRUE(argument.callback_executed);
+ EXPECT_TRUE(argument.threads_stopped);
+
+ // Wait for all threads to spawn before we start terminating them.
+ while (argument.thread_index < kThreadCount) std::this_thread::yield();
+ }
// Signal the threads to terminate.
- advanced_incrementer_thread_exit_mutex.unlock();
- for (uptr i = 0; i < kThreadCount; i++) argument.threads[i].join();
+ for (auto &t : argument.threads) t.join();
}
static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,
More information about the llvm-commits
mailing list