[compiler-rt] 9991ab5 - [sanitizer] Portable sanitizer_stoptheworld_test

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 16 12:54:15 PST 2021


Author: Clemens Wasser
Date: 2021-12-16T12:53:53-08:00
New Revision: 9991ab5df9fa10386c011c2ddb69362902bd690b

URL: https://github.com/llvm/llvm-project/commit/9991ab5df9fa10386c011c2ddb69362902bd690b
DIFF: https://github.com/llvm/llvm-project/commit/9991ab5df9fa10386c011c2ddb69362902bd690b.diff

LOG: [sanitizer] Portable sanitizer_stoptheworld_test

Part of D115204

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 6ea3f7306fef..53911e11e578 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cpp
@@ -10,20 +10,21 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "sanitizer_common/sanitizer_stoptheworld.h"
+
 #include "sanitizer_common/sanitizer_platform.h"
 #if SANITIZER_LINUX && defined(__x86_64__)
 
-#  include <pthread.h>
-#  include <sched.h>
+#  include <mutex>
+#  include <thread>
 
 #  include "gtest/gtest.h"
 #  include "sanitizer_common/sanitizer_common.h"
 #  include "sanitizer_common/sanitizer_libc.h"
-#  include "sanitizer_common/sanitizer_stoptheworld.h"
 
 namespace __sanitizer {
 
-static pthread_mutex_t incrementer_thread_exit_mutex;
+static std::mutex incrementer_thread_exit_mutex;
 
 struct CallbackArgument {
   volatile int counter;
@@ -33,16 +34,16 @@ struct CallbackArgument {
       : counter(0), threads_stopped(false), callback_executed(false) {}
 };
 
-void *IncrementerThread(void *argument) {
-  CallbackArgument *callback_argument = (CallbackArgument *)argument;
+void IncrementerThread(CallbackArgument &callback_argument) {
   while (true) {
-    __sync_fetch_and_add(&callback_argument->counter, 1);
-    if (pthread_mutex_trylock(&incrementer_thread_exit_mutex) == 0) {
-      pthread_mutex_unlock(&incrementer_thread_exit_mutex);
-      return NULL;
-    } else {
-      sched_yield();
+    __sync_fetch_and_add(&callback_argument.counter, 1);
+
+    if (incrementer_thread_exit_mutex.try_lock()) {
+      incrementer_thread_exit_mutex.unlock();
+      return;
     }
+
+    std::this_thread::yield();
   }
 }
 
@@ -54,7 +55,7 @@ void Callback(const SuspendedThreadsList &suspended_threads_list,
   callback_argument->callback_executed = true;
   int counter_at_init = __sync_fetch_and_add(&callback_argument->counter, 0);
   for (uptr i = 0; i < 1000; i++) {
-    sched_yield();
+    std::this_thread::yield();
     if (__sync_fetch_and_add(&callback_argument->counter, 0) !=
         counter_at_init) {
       callback_argument->threads_stopped = false;
@@ -65,22 +66,17 @@ void Callback(const SuspendedThreadsList &suspended_threads_list,
 }
 
 TEST(StopTheWorld, SuspendThreadsSimple) {
-  pthread_mutex_init(&incrementer_thread_exit_mutex, NULL);
   CallbackArgument argument;
-  pthread_t thread_id;
-  int pthread_create_result;
-  pthread_mutex_lock(&incrementer_thread_exit_mutex);
-  pthread_create_result =
-      pthread_create(&thread_id, NULL, IncrementerThread, &argument);
-  ASSERT_EQ(0, pthread_create_result);
+  std::thread thread;
+  incrementer_thread_exit_mutex.lock();
+  ASSERT_NO_THROW(thread = std::thread(IncrementerThread, std::ref(argument)));
   StopTheWorld(&Callback, &argument);
-  pthread_mutex_unlock(&incrementer_thread_exit_mutex);
+  incrementer_thread_exit_mutex.unlock();
   EXPECT_TRUE(argument.callback_executed);
   EXPECT_TRUE(argument.threads_stopped);
   // argument is on stack, so we have to wait for the incrementer thread to
   // terminate before we can return from this function.
-  ASSERT_EQ(0, pthread_join(thread_id, NULL));
-  pthread_mutex_destroy(&incrementer_thread_exit_mutex);
+  ASSERT_NO_THROW(thread.join());
 }
 
 // A more comprehensive test where we spawn a bunch of threads while executing
@@ -88,12 +84,12 @@ TEST(StopTheWorld, SuspendThreadsSimple) {
 static const uptr kThreadCount = 50;
 static const uptr kStopWorldAfter = 10;  // let this many threads spawn first
 
-static pthread_mutex_t advanced_incrementer_thread_exit_mutex;
+static std::mutex advanced_incrementer_thread_exit_mutex;
 
 struct AdvancedCallbackArgument {
   volatile uptr thread_index;
   volatile int counters[kThreadCount];
-  pthread_t thread_ids[kThreadCount];
+  std::thread threads[kThreadCount];
   volatile bool threads_stopped;
   volatile bool callback_executed;
   volatile bool fatal_error;
@@ -104,34 +100,32 @@ struct AdvancedCallbackArgument {
         fatal_error(false) {}
 };
 
-void *AdvancedIncrementerThread(void *argument) {
-  AdvancedCallbackArgument *callback_argument =
-      (AdvancedCallbackArgument *)argument;
+void AdvancedIncrementerThread(AdvancedCallbackArgument &callback_argument) {
   uptr this_thread_index =
-      __sync_fetch_and_add(&callback_argument->thread_index, 1);
+      __sync_fetch_and_add(&callback_argument.thread_index, 1);
   // Spawn the next thread.
   int pthread_create_result;
   if (this_thread_index + 1 < kThreadCount) {
-    pthread_create_result =
-        pthread_create(&callback_argument->thread_ids[this_thread_index + 1],
-                       NULL, AdvancedIncrementerThread, argument);
-    // Cannot use ASSERT_EQ in non-void-returning functions. If there's a
-    // problem, defer failing to the main thread.
-    if (pthread_create_result != 0) {
-      callback_argument->fatal_error = true;
-      __sync_fetch_and_add(&callback_argument->thread_index,
-                           kThreadCount - callback_argument->thread_index);
+    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);
     }
   }
   // Do the actual work.
   while (true) {
-    __sync_fetch_and_add(&callback_argument->counters[this_thread_index], 1);
-    if (pthread_mutex_trylock(&advanced_incrementer_thread_exit_mutex) == 0) {
-      pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
-      return NULL;
-    } else {
-      sched_yield();
+    __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();
+      return;
     }
+
+    std::this_thread::yield();
   }
 }
 
@@ -146,7 +140,7 @@ void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
     counters_at_init[j] =
         __sync_fetch_and_add(&callback_argument->counters[j], 0);
   for (uptr i = 0; i < 10; i++) {
-    sched_yield();
+    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]) {
@@ -158,30 +152,25 @@ void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
 }
 
 TEST(StopTheWorld, SuspendThreadsAdvanced) {
-  pthread_mutex_init(&advanced_incrementer_thread_exit_mutex, NULL);
   AdvancedCallbackArgument argument;
 
-  pthread_mutex_lock(&advanced_incrementer_thread_exit_mutex);
-  int pthread_create_result;
-  pthread_create_result = pthread_create(&argument.thread_ids[0], NULL,
-                                         AdvancedIncrementerThread, &argument);
-  ASSERT_EQ(0, pthread_create_result);
+  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)
-    sched_yield();
+    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)
-    sched_yield();
-  ASSERT_FALSE(argument.fatal_error);  // a pthread_create has failed
+    std::this_thread::yield();
+  ASSERT_FALSE(argument.fatal_error);  // a thread could not be started
   // Signal the threads to terminate.
-  pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
-  for (uptr i = 0; i < kThreadCount; i++)
-    ASSERT_EQ(0, pthread_join(argument.thread_ids[i], NULL));
-  pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex);
+  advanced_incrementer_thread_exit_mutex.unlock();
+  for (uptr i = 0; i < kThreadCount; i++) argument.threads[i].join();
 }
 
 static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,


        


More information about the llvm-commits mailing list