Implement StopTheWorld for Darwin

Reviewers: kubamracek, alekseyshl

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32189

llvm-svn: 300759
This commit is contained in:
Francis Ricci 2017-04-19 21:11:07 +00:00
parent 9b71a402c2
commit eb930609e8
2 changed files with 47 additions and 2 deletions

View File

@ -146,7 +146,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
}
void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
CHECK(0 && "unimplemented");
StopTheWorld(callback, argument);
}
} // namespace __lsan

View File

@ -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__)