[sanitizer] Use tid_t in ThreadLister

llvm-svn: 331921
This commit is contained in:
Vitaly Buka 2018-05-09 21:21:26 +00:00
parent e24f3ff8de
commit 34794a9669
4 changed files with 24 additions and 25 deletions

View File

@ -916,7 +916,7 @@ ThreadLister::ThreadLister(int pid) : pid_(pid), buffer_(4096) {
} }
} }
bool ThreadLister::ListThreads(InternalMmapVector<int> *threads) { bool ThreadLister::ListThreads(InternalMmapVector<tid_t> *threads) {
if (internal_iserror(descriptor_)) if (internal_iserror(descriptor_))
return false; return false;
internal_lseek(descriptor_, 0, SEEK_SET); internal_lseek(descriptor_, 0, SEEK_SET);

View File

@ -74,12 +74,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
// This class reads thread IDs from /proc/<pid>/task using only syscalls. // This class reads thread IDs from /proc/<pid>/task using only syscalls.
class ThreadLister { class ThreadLister {
public: public:
explicit ThreadLister(int pid); explicit ThreadLister(pid_t pid);
~ThreadLister(); ~ThreadLister();
bool ListThreads(InternalMmapVector<int> *threads); bool ListThreads(InternalMmapVector<tid_t> *threads);
private: private:
int pid_; pid_t pid_;
int descriptor_ = -1; int descriptor_ = -1;
InternalMmapVector<char> buffer_; InternalMmapVector<char> buffer_;
}; };

View File

@ -211,7 +211,7 @@ bool ThreadSuspender::SuspendAllThreads() {
ThreadLister thread_lister(pid_); ThreadLister thread_lister(pid_);
bool added_threads; bool added_threads;
bool first_iteration = true; bool first_iteration = true;
InternalMmapVector<int> threads; InternalMmapVector<tid_t> threads;
threads.reserve(128); threads.reserve(128);
do { do {
// Run through the directory entries once. // Run through the directory entries once.
@ -220,7 +220,7 @@ bool ThreadSuspender::SuspendAllThreads() {
ResumeAllThreads(); ResumeAllThreads();
return false; return false;
} }
for (int tid : threads) for (tid_t tid : threads)
if (SuspendThread(tid)) if (SuspendThread(tid))
added_threads = true; added_threads = true;
if (first_iteration && !added_threads) { if (first_iteration && !added_threads) {

View File

@ -45,7 +45,7 @@ struct TidReporterArgument {
pthread_cond_destroy(&tid_reported_cond); pthread_cond_destroy(&tid_reported_cond);
} }
pid_t reported_tid; tid_t reported_tid;
// For signaling to spawned threads that they should terminate. // For signaling to spawned threads that they should terminate.
pthread_cond_t terminate_thread_cond; pthread_cond_t terminate_thread_cond;
pthread_mutex_t terminate_thread_mutex; pthread_mutex_t terminate_thread_mutex;
@ -64,7 +64,7 @@ class ThreadListerTest : public ::testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
pthread_t pthread_id; pthread_t pthread_id;
pid_t tid; tid_t tid;
for (uptr i = 0; i < kThreadCount; i++) { for (uptr i = 0; i < kThreadCount; i++) {
SpawnTidReporter(&pthread_id, &tid); SpawnTidReporter(&pthread_id, &tid);
pthread_ids_.push_back(pthread_id); pthread_ids_.push_back(pthread_id);
@ -81,12 +81,12 @@ class ThreadListerTest : public ::testing::Test {
pthread_join(pthread_ids_[i], NULL); pthread_join(pthread_ids_[i], NULL);
} }
void SpawnTidReporter(pthread_t *pthread_id, pid_t *tid); void SpawnTidReporter(pthread_t *pthread_id, tid_t *tid);
static const uptr kThreadCount = 20; static const uptr kThreadCount = 20;
std::vector<pthread_t> pthread_ids_; std::vector<pthread_t> pthread_ids_;
std::vector<pid_t> tids_; std::vector<tid_t> tids_;
TidReporterArgument thread_arg; TidReporterArgument thread_arg;
}; };
@ -107,44 +107,43 @@ void *TidReporterThread(void *argument) {
return NULL; return NULL;
} }
void ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id, void ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id, tid_t *tid) {
pid_t *tid) {
pthread_mutex_lock(&thread_arg.tid_reported_mutex); pthread_mutex_lock(&thread_arg.tid_reported_mutex);
thread_arg.reported_tid = -1; thread_arg.reported_tid = -1;
ASSERT_EQ(0, pthread_create(pthread_id, NULL, ASSERT_EQ(0, pthread_create(pthread_id, NULL,
TidReporterThread, TidReporterThread,
&thread_arg)); &thread_arg));
while (thread_arg.reported_tid == -1) while (thread_arg.reported_tid == (tid_t)(-1))
pthread_cond_wait(&thread_arg.tid_reported_cond, pthread_cond_wait(&thread_arg.tid_reported_cond,
&thread_arg.tid_reported_mutex); &thread_arg.tid_reported_mutex);
pthread_mutex_unlock(&thread_arg.tid_reported_mutex); pthread_mutex_unlock(&thread_arg.tid_reported_mutex);
*tid = thread_arg.reported_tid; *tid = thread_arg.reported_tid;
} }
static std::vector<pid_t> ReadTidsToVector(ThreadLister *thread_lister) { static std::vector<tid_t> ReadTidsToVector(ThreadLister *thread_lister) {
std::vector<pid_t> listed_tids; std::vector<tid_t> listed_tids;
InternalMmapVector<int> threads(128); InternalMmapVector<tid_t> threads(128);
EXPECT_TRUE(thread_lister->ListThreads(&threads)); EXPECT_TRUE(thread_lister->ListThreads(&threads));
return std::vector<pid_t>(threads.begin(), threads.end()); return std::vector<tid_t>(threads.begin(), threads.end());
} }
static bool Includes(std::vector<pid_t> first, std::vector<pid_t> second) { static bool Includes(std::vector<tid_t> first, std::vector<tid_t> second) {
std::sort(first.begin(), first.end()); std::sort(first.begin(), first.end());
std::sort(second.begin(), second.end()); std::sort(second.begin(), second.end());
return std::includes(first.begin(), first.end(), return std::includes(first.begin(), first.end(),
second.begin(), second.end()); second.begin(), second.end());
} }
static bool HasElement(std::vector<pid_t> vector, pid_t element) { static bool HasElement(const std::vector<tid_t> &vector, tid_t element) {
return std::find(vector.begin(), vector.end(), element) != vector.end(); return std::find(vector.begin(), vector.end(), element) != vector.end();
} }
// ThreadLister's output should include the current thread's TID and the TID of // ThreadLister's output should include the current thread's TID and the TID of
// every thread we spawned. // every thread we spawned.
TEST_F(ThreadListerTest, ThreadListerSeesAllSpawnedThreads) { TEST_F(ThreadListerTest, ThreadListerSeesAllSpawnedThreads) {
pid_t self_tid = GetTid(); tid_t self_tid = GetTid();
ThreadLister thread_lister(getpid()); ThreadLister thread_lister(getpid());
std::vector<pid_t> listed_tids = ReadTidsToVector(&thread_lister); std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister);
ASSERT_TRUE(HasElement(listed_tids, self_tid)); ASSERT_TRUE(HasElement(listed_tids, self_tid));
ASSERT_TRUE(Includes(listed_tids, tids_)); ASSERT_TRUE(Includes(listed_tids, tids_));
} }
@ -155,7 +154,7 @@ TEST_F(ThreadListerTest, DoNotForgetThreads) {
// Run the loop body twice, because ThreadLister might behave differently if // Run the loop body twice, because ThreadLister might behave differently if
// called on a freshly created object. // called on a freshly created object.
for (uptr i = 0; i < 2; i++) { for (uptr i = 0; i < 2; i++) {
std::vector<pid_t> listed_tids = ReadTidsToVector(&thread_lister); std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister);
ASSERT_TRUE(Includes(listed_tids, tids_)); ASSERT_TRUE(Includes(listed_tids, tids_));
} }
} }
@ -164,10 +163,10 @@ TEST_F(ThreadListerTest, DoNotForgetThreads) {
// relisting should cause ThreadLister to recognize their existence. // relisting should cause ThreadLister to recognize their existence.
TEST_F(ThreadListerTest, NewThreads) { TEST_F(ThreadListerTest, NewThreads) {
ThreadLister thread_lister(getpid()); ThreadLister thread_lister(getpid());
std::vector<pid_t> threads_before_extra = ReadTidsToVector(&thread_lister); std::vector<tid_t> threads_before_extra = ReadTidsToVector(&thread_lister);
pthread_t extra_pthread_id; pthread_t extra_pthread_id;
pid_t extra_tid; tid_t extra_tid;
SpawnTidReporter(&extra_pthread_id, &extra_tid); SpawnTidReporter(&extra_pthread_id, &extra_tid);
// Register the new thread so it gets terminated in TearDown(). // Register the new thread so it gets terminated in TearDown().
pthread_ids_.push_back(extra_pthread_id); pthread_ids_.push_back(extra_pthread_id);
@ -177,7 +176,7 @@ TEST_F(ThreadListerTest, NewThreads) {
// so better check for that. // so better check for that.
ASSERT_FALSE(HasElement(threads_before_extra, extra_tid)); ASSERT_FALSE(HasElement(threads_before_extra, extra_tid));
std::vector<pid_t> threads_after_extra = ReadTidsToVector(&thread_lister); std::vector<tid_t> threads_after_extra = ReadTidsToVector(&thread_lister);
ASSERT_TRUE(HasElement(threads_after_extra, extra_tid)); ASSERT_TRUE(HasElement(threads_after_extra, extra_tid));
} }