TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / shared / emugl / common / thread_unittest.cpp
1 // Copyright (C) 2014 The Android Open Source Project
2 //
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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14
15 #include "emugl/common/thread.h"
16
17 #include "emugl/common/mutex.h"
18
19 #include <gtest/gtest.h>
20
21 namespace emugl {
22
23 namespace {
24
25 // A simple thread instance that does nothing at all and exits immediately.
26 class EmptyThread : public ::emugl::Thread {
27 public:
28     intptr_t main() { return 42; }
29 };
30
31 class CountingThread : public ::emugl::Thread {
32 public:
33     class State {
34     public:
35         State() : mLock(), mCount(0) {}
36         ~State() {}
37
38         void increment() {
39             mLock.lock();
40             mCount++;
41             mLock.unlock();
42         }
43
44         int count() const {
45             int ret;
46             mLock.lock();
47             ret = mCount;
48             mLock.unlock();
49             return ret;
50         }
51
52     private:
53         mutable Mutex mLock;
54         int mCount;
55     };
56
57     CountingThread(State* state) : mState(state) {}
58
59     intptr_t main() {
60         mState->increment();
61         return 0;
62     }
63
64 private:
65     State* mState;
66 };
67
68 class WaitingThread : public ::emugl::Thread {
69 public:
70     WaitingThread(Mutex* lock) : mLock(lock) {}
71
72     intptr_t main() {
73         // Try to acquire lock.
74         mLock->lock();
75
76         // Then try to release it.
77         mLock->unlock();
78         return 0;
79     }
80 private:
81     Mutex* mLock;
82 };
83
84 }  // namespace
85
86 TEST(ThreadTest, WaitForSimpleThread) {
87     Thread* thread = new EmptyThread();
88     EXPECT_TRUE(thread);
89     EXPECT_TRUE(thread->start());
90     intptr_t status;
91     EXPECT_TRUE(thread->wait(&status));
92     EXPECT_EQ(42, status);
93 }
94
95 TEST(ThreadTest, WaitForMultipleThreads) {
96     CountingThread::State state;
97     const size_t kMaxThreads = 100;
98     Thread* threads[kMaxThreads];
99
100     // Create all threads.
101     for (size_t n = 0; n < kMaxThreads; ++n) {
102         threads[n] = new CountingThread(&state);
103         EXPECT_TRUE(threads[n]) << "thread " << n;
104     }
105
106     // Start them all.
107     for (size_t n = 0; n < kMaxThreads; ++n) {
108         EXPECT_TRUE(threads[n]->start()) << "thread " << n;
109     }
110
111     // Wait for them all.
112     for (size_t n = 0; n < kMaxThreads; ++n) {
113         EXPECT_TRUE(threads[n]->wait(NULL)) << "thread " << n;
114     }
115
116     // Check state.
117     EXPECT_EQ((int)kMaxThreads, state.count());
118
119     // Delete them all.
120     for (size_t n = 0; n < kMaxThreads; ++n) {
121         delete threads[n];
122     }
123 }
124
125 TEST(ThreadTest, TryWaitForMultipleThreads) {
126     Mutex lock;
127     const size_t kMaxThreads = 100;
128     Thread* threads[kMaxThreads];
129
130     // Create all threads.
131     for (size_t n = 0; n < kMaxThreads; ++n) {
132         threads[n] = new WaitingThread(&lock);
133         EXPECT_TRUE(threads[n]) << "thread " << n;
134     }
135
136     // Acquire the lock, this will block all threads.
137     lock.lock();
138
139     // Start them all.
140     for (size_t n = 0; n < kMaxThreads; ++n) {
141         EXPECT_TRUE(threads[n]->start()) << "thread " << n;
142     }
143
144     // Check that tryWait() fails for all threads.
145     for (size_t n = 0; n < kMaxThreads; ++n) {
146         EXPECT_FALSE(threads[n]->tryWait(NULL)) << "thread" << n;
147     }
148
149     // Release the lock, this will unblock all threads.
150     lock.unlock();
151
152     // Wait for them all.
153     for (size_t n = 0; n < kMaxThreads; ++n) {
154         EXPECT_TRUE(threads[n]->wait(NULL)) << "thread " << n;
155         EXPECT_TRUE(threads[n]->tryWait(NULL)) << "thread " << n;
156     }
157
158     // Delete them all.
159     for (size_t n = 0; n < kMaxThreads; ++n) {
160         delete threads[n];
161     }
162 }
163
164 }  // namespace emugl