Merge "Do a second key cleanup in pthread_exit." into lmp-dev

This commit is contained in:
Christopher Ferris 2014-08-07 00:52:19 +00:00 committed by Android (Google) Code Review
commit 3e7b8e2a8b
2 changed files with 29 additions and 14 deletions

View File

@ -112,6 +112,12 @@ void pthread_exit(void* return_value) {
}
pthread_mutex_unlock(&g_thread_list_lock);
// Perform a second key cleanup. When using jemalloc, a call to free from
// _pthread_internal_remove_locked causes the memory associated with a key
// to be reallocated.
// TODO: When b/16847284 is fixed this call can be removed.
pthread_key_clean_all();
if (user_allocated_stack) {
// Cleaning up this thread's stack is the creator's responsibility, not ours.
__exit(0);

View File

@ -400,27 +400,36 @@ TEST(pthread, pthread_detach__no_such_thread) {
}
TEST(pthread, pthread_detach__leak) {
size_t initial_bytes = mallinfo().uordblks;
size_t initial_bytes = 0;
// Run this loop more than once since the first loop causes some memory
// to be allocated permenantly. Run an extra loop to help catch any subtle
// memory leaks.
for (size_t loop = 0; loop < 3; loop++) {
// Set the initial bytes on the second loop since the memory in use
// should have stabilized.
if (loop == 1) {
initial_bytes = mallinfo().uordblks;
}
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
pthread_attr_t attr;
ASSERT_EQ(0, pthread_attr_init(&attr));
ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
std::vector<pthread_t> threads;
for (size_t i = 0; i < 32; ++i) {
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
threads.push_back(t);
}
std::vector<pthread_t> threads;
for (size_t i = 0; i < 32; ++i) {
pthread_t t;
ASSERT_EQ(0, pthread_create(&t, &attr, IdFn, NULL));
threads.push_back(t);
}
sleep(1);
sleep(1);
for (size_t i = 0; i < 32; ++i) {
ASSERT_EQ(0, pthread_detach(threads[i])) << i;
for (size_t i = 0; i < 32; ++i) {
ASSERT_EQ(0, pthread_detach(threads[i])) << i;
}
}
size_t final_bytes = mallinfo().uordblks;
int leaked_bytes = (final_bytes - initial_bytes);
// User code (like this test) doesn't know how large pthread_internal_t is.