Implement GetThreadCount for Linux.
This commit is contained in:
parent
4f8dc917eb
commit
060b7452ec
|
@ -35,6 +35,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#if GTEST_OS_WINDOWS
|
#if GTEST_OS_WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
@ -83,10 +84,31 @@ const int kStdOutFileno = STDOUT_FILENO;
|
||||||
const int kStdErrFileno = STDERR_FILENO;
|
const int kStdErrFileno = STDERR_FILENO;
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#if GTEST_OS_MAC
|
#if GTEST_OS_LINUX
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename T>
|
||||||
|
T ReadProcFileField(const string& filename, int field) {
|
||||||
|
std::string dummy;
|
||||||
|
std::ifstream file(filename.c_str());
|
||||||
|
while (field-- > 0) {
|
||||||
|
file >> dummy;
|
||||||
|
}
|
||||||
|
T output = 0;
|
||||||
|
file >> output;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Returns the number of active threads, or 0 when there is an error.
|
||||||
|
size_t GetThreadCount() {
|
||||||
|
const string filename =
|
||||||
|
(Message() << "/proc/" << getpid() << "/stat").GetString();
|
||||||
|
return ReadProcFileField<int>(filename, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif GTEST_OS_MAC
|
||||||
|
|
||||||
// Returns the number of threads running in the process, or 0 to indicate that
|
|
||||||
// we cannot detect it.
|
|
||||||
size_t GetThreadCount() {
|
size_t GetThreadCount() {
|
||||||
const task_t task = mach_task_self();
|
const task_t task = mach_task_self();
|
||||||
mach_msg_type_number_t thread_count;
|
mach_msg_type_number_t thread_count;
|
||||||
|
@ -132,7 +154,7 @@ size_t GetThreadCount() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GTEST_OS_MAC
|
#endif // GTEST_OS_LINUX
|
||||||
|
|
||||||
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
|
||||||
|
|
||||||
|
|
|
@ -304,58 +304,51 @@ TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) {
|
||||||
EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
|
EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTEST_OS_MAC || GTEST_OS_QNX
|
#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
|
||||||
void* ThreadFunc(void* data) {
|
void* ThreadFunc(void* data) {
|
||||||
pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
|
internal::Mutex* mutex = static_cast<internal::Mutex*>(data);
|
||||||
pthread_mutex_lock(mutex);
|
mutex->Lock();
|
||||||
pthread_mutex_unlock(mutex);
|
mutex->Unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(GetThreadCountTest, ReturnsCorrectValue) {
|
TEST(GetThreadCountTest, ReturnsCorrectValue) {
|
||||||
EXPECT_EQ(1U, GetThreadCount());
|
const size_t starting_count = GetThreadCount();
|
||||||
pthread_mutex_t mutex;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pthread_t thread_id;
|
pthread_t thread_id;
|
||||||
|
|
||||||
// TODO(vladl@google.com): turn mutex into internal::Mutex for automatic
|
internal::Mutex mutex;
|
||||||
// destruction.
|
{
|
||||||
pthread_mutex_init(&mutex, NULL);
|
internal::MutexLock lock(&mutex);
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_attr_t attr;
|
||||||
ASSERT_EQ(0, pthread_attr_init(&attr));
|
ASSERT_EQ(0, pthread_attr_init(&attr));
|
||||||
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
|
||||||
|
|
||||||
const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
|
const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
|
||||||
ASSERT_EQ(0, pthread_attr_destroy(&attr));
|
ASSERT_EQ(0, pthread_attr_destroy(&attr));
|
||||||
ASSERT_EQ(0, status);
|
ASSERT_EQ(0, status);
|
||||||
EXPECT_EQ(2U, GetThreadCount());
|
EXPECT_EQ(starting_count + 1, GetThreadCount());
|
||||||
pthread_mutex_unlock(&mutex);
|
}
|
||||||
|
|
||||||
void* dummy;
|
void* dummy;
|
||||||
ASSERT_EQ(0, pthread_join(thread_id, &dummy));
|
ASSERT_EQ(0, pthread_join(thread_id, &dummy));
|
||||||
|
|
||||||
# if GTEST_OS_MAC
|
// The OS may not immediately report the updated thread count after
|
||||||
|
|
||||||
// MacOS X may not immediately report the updated thread count after
|
|
||||||
// joining a thread, causing flakiness in this test. To counter that, we
|
// joining a thread, causing flakiness in this test. To counter that, we
|
||||||
// wait for up to .5 seconds for the OS to report the correct value.
|
// wait for up to .5 seconds for the OS to report the correct value.
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
if (GetThreadCount() == 1)
|
if (GetThreadCount() == starting_count)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
SleepMilliseconds(100);
|
SleepMilliseconds(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif // GTEST_OS_MAC
|
EXPECT_EQ(starting_count, GetThreadCount());
|
||||||
|
|
||||||
EXPECT_EQ(1U, GetThreadCount());
|
|
||||||
pthread_mutex_destroy(&mutex);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
|
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
|
||||||
EXPECT_EQ(0U, GetThreadCount());
|
EXPECT_EQ(0U, GetThreadCount());
|
||||||
}
|
}
|
||||||
#endif // GTEST_OS_MAC || GTEST_OS_QNX
|
#endif // GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_QNX
|
||||||
|
|
||||||
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
|
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
|
||||||
const bool a_false_condition = false;
|
const bool a_false_condition = false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user