Clean up the pthread key tests.
The previous pthread_key_create_many test was really pthread_key_create_all, which has proven very difficult to test correctly (because it is affected by any other parts of the system using pthread keys, and that can vary with test ordering). It also tested expected values of PTHREAD_KEYS_MAX and the associated sysconf() value, rather than those being in their own test. Instead, split this test into a few distinct tests: * pthread.pthread_keys_max * pthread._SC_THREAD_KEYS_MAX_big_enough_for_POSIX * pthread.pthread_key_many_distinct * We actually didn't have a test to ensure that the keys we were creating were distinct. * pthread.pthread_key_EAGAIN * Make sure pthread_key_create() will _eventually_ fail with EAGAIN, not at a (sometimes incorrectly) predetermined maximum. Change-Id: Iff1e4fdcc02404094bde0418122c64c227cf1702
This commit is contained in:
parent
0481471b1b
commit
c4bcc75f09
@ -38,37 +38,71 @@ TEST(pthread, pthread_key_create) {
|
||||
ASSERT_EQ(EINVAL, pthread_key_delete(key));
|
||||
}
|
||||
|
||||
TEST(pthread, pthread_key_create_lots) {
|
||||
#if defined(__BIONIC__) // glibc uses keys internally that its sysconf value doesn't account for.
|
||||
TEST(pthread, pthread_keys_max) {
|
||||
// POSIX says PTHREAD_KEYS_MAX should be at least 128.
|
||||
ASSERT_GE(PTHREAD_KEYS_MAX, 128);
|
||||
}
|
||||
|
||||
TEST(pthread, _SC_THREAD_KEYS_MAX_big_enough_for_POSIX) {
|
||||
// sysconf shouldn't return a smaller value.
|
||||
int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX);
|
||||
ASSERT_GE(sysconf_max, PTHREAD_KEYS_MAX);
|
||||
}
|
||||
|
||||
TEST(pthread, pthread_key_many_distinct) {
|
||||
// We should be able to allocate at least this many keys.
|
||||
int nkeys = sysconf(_SC_THREAD_KEYS_MAX) / 2;
|
||||
std::vector<pthread_key_t> keys;
|
||||
|
||||
auto scope_guard = make_scope_guard([&keys]{
|
||||
for (auto key : keys) {
|
||||
EXPECT_EQ(0, pthread_key_delete(key));
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < nkeys; ++i) {
|
||||
pthread_key_t key;
|
||||
// If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is
|
||||
// wrong.
|
||||
ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << nkeys;
|
||||
keys.push_back(key);
|
||||
ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i)));
|
||||
}
|
||||
|
||||
for (int i = keys.size() - 1; i >= 0; --i) {
|
||||
ASSERT_EQ(reinterpret_cast<void*>(i), pthread_getspecific(keys.back()));
|
||||
pthread_key_t key = keys.back();
|
||||
keys.pop_back();
|
||||
ASSERT_EQ(0, pthread_key_delete(key));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(pthread, pthread_key_EAGAIN) {
|
||||
int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX);
|
||||
|
||||
// sysconf shouldn't return a smaller value.
|
||||
ASSERT_GE(sysconf_max, PTHREAD_KEYS_MAX);
|
||||
|
||||
// We can allocate _SC_THREAD_KEYS_MAX keys.
|
||||
sysconf_max -= 2; // (Except that gtest takes two for itself.)
|
||||
std::vector<pthread_key_t> keys;
|
||||
for (int i = 0; i < sysconf_max; ++i) {
|
||||
int rv = 0;
|
||||
// Two keys are used by gtest, so sysconf_max should be more than we are
|
||||
// allowed to allocate now.
|
||||
for (int i = 0; i < sysconf_max; i++) {
|
||||
pthread_key_t key;
|
||||
// If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is wrong.
|
||||
ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << sysconf_max;
|
||||
rv = pthread_key_create(&key, NULL);
|
||||
if (rv == EAGAIN) {
|
||||
break;
|
||||
}
|
||||
EXPECT_EQ(0, rv);
|
||||
keys.push_back(key);
|
||||
}
|
||||
|
||||
// ...and that really is the maximum.
|
||||
pthread_key_t key;
|
||||
ASSERT_EQ(EAGAIN, pthread_key_create(&key, NULL));
|
||||
|
||||
// (Don't leak all those keys!)
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
ASSERT_EQ(0, pthread_key_delete(keys[i]));
|
||||
// Don't leak keys.
|
||||
for (auto key : keys) {
|
||||
EXPECT_EQ(0, pthread_key_delete(key));
|
||||
}
|
||||
#else // __BIONIC__
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif // __BIONIC__
|
||||
keys.clear();
|
||||
|
||||
// We should have eventually reached the maximum number of keys and received
|
||||
// EAGAIN.
|
||||
ASSERT_EQ(EAGAIN, rv);
|
||||
}
|
||||
|
||||
TEST(pthread, pthread_key_delete) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user