1 // Copyright (C) 2014 The Android Open Source Project
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #include "emugl/common/thread_store.h"
17 #include "emugl/common/mutex.h"
18 #include "emugl/common/testing/test_thread.h"
20 #include <gtest/gtest.h>
26 // Helper class used to count instance creation and destruction.
34 Mutex::AutoLock lock(mMutex);
35 if (mCreationCount < kMaxInstances)
36 mInstances[mCreationCount] = this;
41 Mutex::AutoLock lock(mMutex);
46 Mutex::AutoLock lock(mMutex);
48 mDestructionCount = 0;
51 static size_t getCreationCount() {
52 Mutex::AutoLock lock(mMutex);
53 return mCreationCount;
56 static size_t getDestructionCount() {
57 Mutex::AutoLock lock(mMutex);
58 return mDestructionCount;
61 static void freeAll() {
62 for (size_t n = 0; n < kMaxInstances; ++n)
68 static size_t mCreationCount;
69 static size_t mDestructionCount;
70 static StaticCounter* mInstances[kMaxInstances];
73 Mutex StaticCounter::mMutex;
74 size_t StaticCounter::mCreationCount = 0;
75 size_t StaticCounter::mDestructionCount = 0;
76 StaticCounter* StaticCounter::mInstances[kMaxInstances];
80 // Just check that we can create a new ThreadStore with an empty
81 // destructor, and use it in the current thread.
82 TEST(ThreadStore, MainThreadWithoutDestructor) {
83 ThreadStore store(NULL);
86 EXPECT_EQ(&x, store.get());
89 // The following test checks that exiting a thread correctly deletes
90 // any thread-local value stored in it.
91 static void simplyDestroy(void* value) {
92 delete (StaticCounter*) value;
95 static void* simpleThreadFunc(void* param) {
96 ThreadStore* store = static_cast<ThreadStore*>(param);
97 store->set(new StaticCounter());
98 ThreadStore::OnThreadExit();
102 TEST(ThreadStore, ThreadsWithDestructor) {
103 ThreadStore store(simplyDestroy);
104 const size_t kNumThreads = 1000;
105 TestThread* threads[kNumThreads];
106 StaticCounter::reset();
108 for (size_t n = 0; n < kNumThreads; ++n) {
109 threads[n] = new TestThread(&simpleThreadFunc, &store);
111 for (size_t n = 0; n < kNumThreads; ++n) {
115 EXPECT_EQ(kNumThreads, StaticCounter::getCreationCount());
116 EXPECT_EQ(kNumThreads, StaticCounter::getDestructionCount());
118 for (size_t n = 0; n < kNumThreads; ++n) {
123 TEST(ThreadStore, ThreadsWithoutDestructor) {
124 ThreadStore store(NULL);
125 const size_t kNumThreads = 1000;
126 TestThread* threads[kNumThreads];
127 StaticCounter::reset();
129 for (size_t n = 0; n < kNumThreads; ++n) {
130 threads[n] = new TestThread(&simpleThreadFunc, &store);
132 for (size_t n = 0; n < kNumThreads; ++n) {
136 EXPECT_EQ(kNumThreads, StaticCounter::getCreationCount());
137 EXPECT_EQ(0U, StaticCounter::getDestructionCount());
139 StaticCounter::freeAll();
141 for (size_t n = 0; n < kNumThreads; ++n) {