diff options
| author | Francis Ricci <francisjricci@gmail.com> | 2017-04-19 21:11:07 +0000 | 
|---|---|---|
| committer | Francis Ricci <francisjricci@gmail.com> | 2017-04-19 21:11:07 +0000 | 
| commit | eb930609e8452ec8281f1f62fdb741396df46ed0 (patch) | |
| tree | a94c4592c923d36c1c8d0d1e0c622575a2dc16d7 | |
| parent | 9b71a402c2809f99e43bb4b29486d1293461e2a4 (diff) | |
| download | bcm5719-llvm-eb930609e8452ec8281f1f62fdb741396df46ed0.tar.gz bcm5719-llvm-eb930609e8452ec8281f1f62fdb741396df46ed0.zip  | |
Implement StopTheWorld for Darwin
Reviewers: kubamracek, alekseyshl
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D32189
llvm-svn: 300759
| -rw-r--r-- | compiler-rt/lib/lsan/lsan_common_mac.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc | 47 | 
2 files changed, 47 insertions, 2 deletions
diff --git a/compiler-rt/lib/lsan/lsan_common_mac.cc b/compiler-rt/lib/lsan/lsan_common_mac.cc index 20ac389d534..a158b6512ba 100644 --- a/compiler-rt/lib/lsan/lsan_common_mac.cc +++ b/compiler-rt/lib/lsan/lsan_common_mac.cc @@ -146,7 +146,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {  }  void DoStopTheWorld(StopTheWorldCallback callback, void *argument) { -  CHECK(0 && "unimplemented"); +  StopTheWorld(callback, argument);  }  } // namespace __lsan diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc index 281db96f672..20b8760935b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc @@ -17,6 +17,8 @@                        defined(__i386))  #include <mach/mach.h> +#include <mach/thread_info.h> +#include <pthread.h>  #include "sanitizer_stoptheworld.h" @@ -44,8 +46,51 @@ class SuspendedThreadsListMac : public SuspendedThreadsList {    InternalMmapVector<SuspendedThreadInfo> threads_;  }; +struct RunThreadArgs { +  StopTheWorldCallback callback; +  void *argument; +}; + +void RunThread(void *arg) { +  struct RunThreadArgs *run_args = (struct RunThreadArgs *)arg; +  SuspendedThreadsListMac suspended_threads_list; + +  mach_port_t task; +  kern_return_t err = task_for_pid(mach_task_self(), internal_getpid(), &task); +  if (err != KERN_SUCCESS) { +    VReport(1, "Getting task from pid failed (errno %d).\n", err); +    return; +  } + +  thread_array_t threads; +  mach_msg_type_number_t num_threads; + +  err = task_threads(task, &threads, &num_threads); +  if (err != KERN_SUCCESS) { +    VReport(1, "Failed to get threads for task (errno %d).\n", err); +    return; +  } + +  thread_t thread_self = mach_thread_self(); +  for (unsigned int i = 0; i < num_threads; ++i) { +    if (threads[i] == thread_self) continue; + +    thread_suspend(threads[i]); +    suspended_threads_list.Append(threads[i]); +  } + +  run_args->callback(suspended_threads_list, run_args->argument); + +  uptr num_suspended = suspended_threads_list.ThreadCount(); +  for (unsigned int i = 0; i < num_suspended; ++i) { +    thread_resume(suspended_threads_list.GetThread(i)); +  } +} +  void StopTheWorld(StopTheWorldCallback callback, void *argument) { -  CHECK(0 && "unimplemented"); +  struct RunThreadArgs arg = {callback, argument}; +  pthread_t run_thread = (pthread_t)internal_start_thread(RunThread, &arg); +  internal_join_thread(run_thread);  }  #if defined(__x86_64__)  | 

