forked from OSchip/llvm-project
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:
parent
9b71a402c2
commit
eb930609e8
|
@ -146,7 +146,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) {
|
|||
}
|
||||
|
||||
void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
|
||||
CHECK(0 && "unimplemented");
|
||||
StopTheWorld(callback, argument);
|
||||
}
|
||||
|
||||
} // namespace __lsan
|
||||
|
|
|
@ -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__)
|
||||
|
|
Loading…
Reference in New Issue