summaryrefslogtreecommitdiffstats
path: root/tests/pthread_test.cpp
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2014-09-30 11:48:24 -0700
committerDan Albert <danalbert@google.com>2014-09-30 15:40:14 -0700
commitc4bcc75f094206f3a6af767a5f6033ad44253b70 (patch)
tree31cddb500d4291b6466634e7a303d7c7035cc4b8 /tests/pthread_test.cpp
parent0481471b1bb95a90f632a9fb59c7a1767b9836c8 (diff)
downloadbionic-c4bcc75f094206f3a6af767a5f6033ad44253b70.zip
bionic-c4bcc75f094206f3a6af767a5f6033ad44253b70.tar.gz
bionic-c4bcc75f094206f3a6af767a5f6033ad44253b70.tar.bz2
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
Diffstat (limited to 'tests/pthread_test.cpp')
-rw-r--r--tests/pthread_test.cpp70
1 files changed, 52 insertions, 18 deletions
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 9dbb4f5..01de09f 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -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);
+}
- int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX);
-
+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);
+}
- // We can allocate _SC_THREAD_KEYS_MAX keys.
- sysconf_max -= 2; // (Except that gtest takes two for itself.)
+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;
- for (int i = 0; i < sysconf_max; ++i) {
+
+ 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 " << sysconf_max;
+ // 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)));
}
- // ...and that really is the maximum.
- pthread_key_t key;
- ASSERT_EQ(EAGAIN, pthread_key_create(&key, NULL));
+ 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));
+ }
+}
- // (Don't leak all those keys!)
- for (size_t i = 0; i < keys.size(); ++i) {
- ASSERT_EQ(0, pthread_key_delete(keys[i]));
+TEST(pthread, pthread_key_EAGAIN) {
+ int sysconf_max = sysconf(_SC_THREAD_KEYS_MAX);
+
+ std::vector<pthread_key_t> keys;
+ 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;
+ rv = pthread_key_create(&key, NULL);
+ if (rv == EAGAIN) {
+ break;
+ }
+ EXPECT_EQ(0, rv);
+ keys.push_back(key);
}
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
+
+ // Don't leak keys.
+ for (auto key : keys) {
+ EXPECT_EQ(0, pthread_key_delete(key));
+ }
+ keys.clear();
+
+ // We should have eventually reached the maximum number of keys and received
+ // EAGAIN.
+ ASSERT_EQ(EAGAIN, rv);
}
TEST(pthread, pthread_key_delete) {