Commit 22e6055c by Abseil Team Committed by Andy Soffer

Googletest export

Make multiple attempts to verify GetThreadCount() Testing GetThreadCount() is inheritently noisy, as other threads can be started or destroyed between two calls to GetThreadCount(). This is especially true under certain analyzer configurations, such as TSAN. PiperOrigin-RevId: 381951799
parent 255323cf
...@@ -289,36 +289,61 @@ void* ThreadFunc(void* data) { ...@@ -289,36 +289,61 @@ void* ThreadFunc(void* data) {
} }
TEST(GetThreadCountTest, ReturnsCorrectValue) { TEST(GetThreadCountTest, ReturnsCorrectValue) {
const size_t starting_count = GetThreadCount(); size_t starting_count;
pthread_t thread_id; size_t thread_count_after_create;
size_t thread_count_after_join;
// We can't guarantee that no other thread was created or destroyed between
// any two calls to GetThreadCount(). We make multiple attempts, hoping that
// background noise is not constant and we would see the "right" values at
// some point.
for (int attempt = 0; attempt < 20; ++attempt) {
starting_count = GetThreadCount();
pthread_t thread_id;
internal::Mutex mutex;
{
internal::MutexLock lock(&mutex);
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
ASSERT_EQ(0, pthread_attr_destroy(&attr));
ASSERT_EQ(0, status);
}
internal::Mutex mutex; thread_count_after_create = GetThreadCount();
{
internal::MutexLock lock(&mutex);
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
ASSERT_EQ(0, pthread_attr_destroy(&attr));
ASSERT_EQ(0, status);
EXPECT_EQ(starting_count + 1, GetThreadCount());
}
void* dummy; void* dummy;
ASSERT_EQ(0, pthread_join(thread_id, &dummy)); ASSERT_EQ(0, pthread_join(thread_id, &dummy));
// The OS may not immediately report the updated thread count after // Join before we decide whether we need to retry the test. Retry if an
// joining a thread, causing flakiness in this test. To counter that, we // arbitrary other thread was created or destroyed in the meantime.
// wait for up to .5 seconds for the OS to report the correct value. if (thread_count_after_create != starting_count + 1) continue;
for (int i = 0; i < 5; ++i) {
if (GetThreadCount() == starting_count) // The OS may not immediately report the updated thread count after
break; // 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.
bool thread_count_matches = false;
for (int i = 0; i < 5; ++i) {
thread_count_after_join = GetThreadCount();
if (thread_count_after_join == starting_count) {
thread_count_matches = true;
break;
}
SleepMilliseconds(100);
}
// Retry if an arbitrary other thread was created or destroyed.
if (!thread_count_matches) continue;
SleepMilliseconds(100); break;
} }
EXPECT_EQ(starting_count, GetThreadCount()); EXPECT_EQ(thread_count_after_create, starting_count + 1);
EXPECT_EQ(thread_count_after_join, starting_count);
} }
#else #else
TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) { TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment