forked from OSchip/llvm-project
Remove InternalAlloc/InternalFree calls from StopTheWorld. Patch by Sergey Matveev.
llvm-svn: 178855
This commit is contained in:
parent
6b53a2f50a
commit
46b8665ea4
|
@ -651,8 +651,9 @@ int internal_sigaltstack(const struct sigaltstack *ss,
|
||||||
ThreadLister::ThreadLister(int pid)
|
ThreadLister::ThreadLister(int pid)
|
||||||
: pid_(pid),
|
: pid_(pid),
|
||||||
descriptor_(-1),
|
descriptor_(-1),
|
||||||
|
buffer_(4096),
|
||||||
error_(true),
|
error_(true),
|
||||||
entry_((linux_dirent *)buffer_),
|
entry_((struct linux_dirent *)buffer_.data()),
|
||||||
bytes_read_(0) {
|
bytes_read_(0) {
|
||||||
char task_directory_path[80];
|
char task_directory_path[80];
|
||||||
internal_snprintf(task_directory_path, sizeof(task_directory_path),
|
internal_snprintf(task_directory_path, sizeof(task_directory_path),
|
||||||
|
@ -700,8 +701,8 @@ bool ThreadLister::GetDirectoryEntries() {
|
||||||
CHECK_GE(descriptor_, 0);
|
CHECK_GE(descriptor_, 0);
|
||||||
CHECK_NE(error_, true);
|
CHECK_NE(error_, true);
|
||||||
bytes_read_ = internal_getdents(descriptor_,
|
bytes_read_ = internal_getdents(descriptor_,
|
||||||
(struct linux_dirent *)buffer_,
|
(struct linux_dirent *)buffer_.data(),
|
||||||
sizeof(buffer_));
|
buffer_.size());
|
||||||
if (bytes_read_ < 0) {
|
if (bytes_read_ < 0) {
|
||||||
Report("Can't read directory entries from /proc/%d/task.\n", pid_);
|
Report("Can't read directory entries from /proc/%d/task.\n", pid_);
|
||||||
error_ = true;
|
error_ = true;
|
||||||
|
@ -709,7 +710,7 @@ bool ThreadLister::GetDirectoryEntries() {
|
||||||
} else if (bytes_read_ == 0) {
|
} else if (bytes_read_ == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
entry_ = (struct linux_dirent *)buffer_;
|
entry_ = (struct linux_dirent *)buffer_.data();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#ifndef SANITIZER_LINUX_H
|
#ifndef SANITIZER_LINUX_H
|
||||||
#define SANITIZER_LINUX_H
|
#define SANITIZER_LINUX_H
|
||||||
|
|
||||||
|
#include "sanitizer_common.h"
|
||||||
#include "sanitizer_internal_defs.h"
|
#include "sanitizer_internal_defs.h"
|
||||||
|
|
||||||
struct sigaltstack;
|
struct sigaltstack;
|
||||||
|
@ -43,7 +44,7 @@ class ThreadLister {
|
||||||
|
|
||||||
int pid_;
|
int pid_;
|
||||||
int descriptor_;
|
int descriptor_;
|
||||||
char buffer_[4096];
|
InternalScopedBuffer<char> buffer_;
|
||||||
bool error_;
|
bool error_;
|
||||||
struct linux_dirent* entry_;
|
struct linux_dirent* entry_;
|
||||||
int bytes_read_;
|
int bytes_read_;
|
||||||
|
|
|
@ -148,27 +148,24 @@ void ThreadSuspender::KillAllThreads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadSuspender::SuspendAllThreads() {
|
bool ThreadSuspender::SuspendAllThreads() {
|
||||||
void *mem = InternalAlloc(sizeof(ThreadLister));
|
ThreadLister thread_lister(pid_);
|
||||||
ThreadLister *thread_lister = new(mem) ThreadLister(pid_);
|
|
||||||
bool added_threads;
|
bool added_threads;
|
||||||
do {
|
do {
|
||||||
// Run through the directory entries once.
|
// Run through the directory entries once.
|
||||||
added_threads = false;
|
added_threads = false;
|
||||||
pid_t tid = thread_lister->GetNextTID();
|
pid_t tid = thread_lister.GetNextTID();
|
||||||
while (tid >= 0) {
|
while (tid >= 0) {
|
||||||
if (SuspendThread(tid))
|
if (SuspendThread(tid))
|
||||||
added_threads = true;
|
added_threads = true;
|
||||||
tid = thread_lister->GetNextTID();
|
tid = thread_lister.GetNextTID();
|
||||||
}
|
}
|
||||||
if (thread_lister->error()) {
|
if (thread_lister.error()) {
|
||||||
// Detach threads and fail.
|
// Detach threads and fail.
|
||||||
ResumeAllThreads();
|
ResumeAllThreads();
|
||||||
InternalFree(mem);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
thread_lister->Reset();
|
thread_lister.Reset();
|
||||||
} while (added_threads);
|
} while (added_threads);
|
||||||
InternalFree(mem);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue