Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: test/base-unittests/platform/condition-variable-unittest.cc

Issue 448603002: Refactor unit tests for the base library to use GTest. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Reduce LoopIncrement test time. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/base/platform/condition-variable.h"
6
7 #include "src/base/platform/platform.h"
8 #include "src/base/platform/time.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace v8 {
12 namespace base {
13
14 TEST(ConditionVariable, WaitForAfterNofityOnSameThread) {
15 for (int n = 0; n < 10; ++n) {
16 Mutex mutex;
17 ConditionVariable cv;
18
19 LockGuard<Mutex> lock_guard(&mutex);
20
21 cv.NotifyOne();
22 EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
23
24 cv.NotifyAll();
25 EXPECT_FALSE(cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n)));
26 }
27 }
28
29
30 namespace {
31
32 class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread {
33 public:
34 ThreadWithMutexAndConditionVariable()
35 : Thread("ThreadWithMutexAndConditionVariable"),
36 running_(false), finished_(false) {}
37 virtual ~ThreadWithMutexAndConditionVariable() {}
38
39 virtual void Run() V8_OVERRIDE {
40 LockGuard<Mutex> lock_guard(&mutex_);
41 running_ = true;
42 cv_.NotifyOne();
43 while (running_) {
44 cv_.Wait(&mutex_);
45 }
46 finished_ = true;
47 cv_.NotifyAll();
48 }
49
50 bool running_;
51 bool finished_;
52 ConditionVariable cv_;
53 Mutex mutex_;
54 };
55
56 }
57
58
59 TEST(ConditionVariable, MultipleThreadsWithSeparateConditionVariables) {
60 static const int kThreadCount = 128;
61 ThreadWithMutexAndConditionVariable threads[kThreadCount];
62
63 for (int n = 0; n < kThreadCount; ++n) {
64 LockGuard<Mutex> lock_guard(&threads[n].mutex_);
65 EXPECT_FALSE(threads[n].running_);
66 EXPECT_FALSE(threads[n].finished_);
67 threads[n].Start();
68 // Wait for nth thread to start.
69 while (!threads[n].running_) {
70 threads[n].cv_.Wait(&threads[n].mutex_);
71 }
72 }
73
74 for (int n = kThreadCount - 1; n >= 0; --n) {
75 LockGuard<Mutex> lock_guard(&threads[n].mutex_);
76 EXPECT_TRUE(threads[n].running_);
77 EXPECT_FALSE(threads[n].finished_);
78 }
79
80 for (int n = 0; n < kThreadCount; ++n) {
81 LockGuard<Mutex> lock_guard(&threads[n].mutex_);
82 EXPECT_TRUE(threads[n].running_);
83 EXPECT_FALSE(threads[n].finished_);
84 // Tell the nth thread to quit.
85 threads[n].running_ = false;
86 threads[n].cv_.NotifyOne();
87 }
88
89 for (int n = kThreadCount - 1; n >= 0; --n) {
90 // Wait for nth thread to quit.
91 LockGuard<Mutex> lock_guard(&threads[n].mutex_);
92 while (!threads[n].finished_) {
93 threads[n].cv_.Wait(&threads[n].mutex_);
94 }
95 EXPECT_FALSE(threads[n].running_);
96 EXPECT_TRUE(threads[n].finished_);
97 }
98
99 for (int n = 0; n < kThreadCount; ++n) {
100 threads[n].Join();
101 LockGuard<Mutex> lock_guard(&threads[n].mutex_);
102 EXPECT_FALSE(threads[n].running_);
103 EXPECT_TRUE(threads[n].finished_);
104 }
105 }
106
107
108 namespace {
109
110 class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread {
111 public:
112 ThreadWithSharedMutexAndConditionVariable()
113 : Thread("ThreadWithSharedMutexAndConditionVariable"),
114 running_(false), finished_(false), cv_(NULL), mutex_(NULL) {}
115 virtual ~ThreadWithSharedMutexAndConditionVariable() {}
116
117 virtual void Run() V8_OVERRIDE {
118 LockGuard<Mutex> lock_guard(mutex_);
119 running_ = true;
120 cv_->NotifyAll();
121 while (running_) {
122 cv_->Wait(mutex_);
123 }
124 finished_ = true;
125 cv_->NotifyAll();
126 }
127
128 bool running_;
129 bool finished_;
130 ConditionVariable* cv_;
131 Mutex* mutex_;
132 };
133
134 }
135
136
137 TEST(ConditionVariable, MultipleThreadsWithSharedSeparateConditionVariables) {
138 static const int kThreadCount = 128;
139 ThreadWithSharedMutexAndConditionVariable threads[kThreadCount];
140 ConditionVariable cv;
141 Mutex mutex;
142
143 for (int n = 0; n < kThreadCount; ++n) {
144 threads[n].mutex_ = &mutex;
145 threads[n].cv_ = &cv;
146 }
147
148 // Start all threads.
149 {
150 LockGuard<Mutex> lock_guard(&mutex);
151 for (int n = 0; n < kThreadCount; ++n) {
152 EXPECT_FALSE(threads[n].running_);
153 EXPECT_FALSE(threads[n].finished_);
154 threads[n].Start();
155 }
156 }
157
158 // Wait for all threads to start.
159 {
160 LockGuard<Mutex> lock_guard(&mutex);
161 for (int n = kThreadCount - 1; n >= 0; --n) {
162 while (!threads[n].running_) {
163 cv.Wait(&mutex);
164 }
165 }
166 }
167
168 // Make sure that all threads are running.
169 {
170 LockGuard<Mutex> lock_guard(&mutex);
171 for (int n = 0; n < kThreadCount; ++n) {
172 EXPECT_TRUE(threads[n].running_);
173 EXPECT_FALSE(threads[n].finished_);
174 }
175 }
176
177 // Tell all threads to quit.
178 {
179 LockGuard<Mutex> lock_guard(&mutex);
180 for (int n = kThreadCount - 1; n >= 0; --n) {
181 EXPECT_TRUE(threads[n].running_);
182 EXPECT_FALSE(threads[n].finished_);
183 // Tell the nth thread to quit.
184 threads[n].running_ = false;
185 }
186 cv.NotifyAll();
187 }
188
189 // Wait for all threads to quit.
190 {
191 LockGuard<Mutex> lock_guard(&mutex);
192 for (int n = 0; n < kThreadCount; ++n) {
193 while (!threads[n].finished_) {
194 cv.Wait(&mutex);
195 }
196 }
197 }
198
199 // Make sure all threads are finished.
200 {
201 LockGuard<Mutex> lock_guard(&mutex);
202 for (int n = kThreadCount - 1; n >= 0; --n) {
203 EXPECT_FALSE(threads[n].running_);
204 EXPECT_TRUE(threads[n].finished_);
205 }
206 }
207
208 // Join all threads.
209 for (int n = 0; n < kThreadCount; ++n) {
210 threads[n].Join();
211 }
212 }
213
214
215 namespace {
216
217 class LoopIncrementThread V8_FINAL : public Thread {
218 public:
219 LoopIncrementThread(int rem,
220 int* counter,
221 int limit,
222 int thread_count,
223 ConditionVariable* cv,
224 Mutex* mutex)
225 : Thread("LoopIncrementThread"), rem_(rem), counter_(counter),
226 limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex) {
227 EXPECT_LT(rem, thread_count);
228 EXPECT_EQ(0, limit % thread_count);
229 }
230
231 virtual void Run() V8_OVERRIDE {
232 int last_count = -1;
233 while (true) {
234 LockGuard<Mutex> lock_guard(mutex_);
235 int count = *counter_;
236 while (count % thread_count_ != rem_ && count < limit_) {
237 cv_->Wait(mutex_);
238 count = *counter_;
239 }
240 if (count >= limit_) break;
241 EXPECT_EQ(*counter_, count);
242 if (last_count != -1) {
243 EXPECT_EQ(last_count + (thread_count_ - 1), count);
244 }
245 count++;
246 *counter_ = count;
247 last_count = count;
248 cv_->NotifyAll();
249 }
250 }
251
252 private:
253 const int rem_;
254 int* counter_;
255 const int limit_;
256 const int thread_count_;
257 ConditionVariable* cv_;
258 Mutex* mutex_;
259 };
260
261 }
262
263
264 TEST(ConditionVariable, LoopIncrement) {
265 static const int kMaxThreadCount = 16;
266 Mutex mutex;
267 ConditionVariable cv;
268 for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) {
269 int limit = thread_count * 10;
270 int counter = 0;
271
272 // Setup the threads.
273 Thread** threads = new Thread*[thread_count];
Sven Panne 2014/08/06 09:33:28 Use ScopedVector? Or do we explicitly want to avoi
Benedikt Meurer 2014/08/06 09:35:06 ScopedVector is not in base.
274 for (int n = 0; n < thread_count; ++n) {
275 threads[n] = new LoopIncrementThread(
276 n, &counter, limit, thread_count, &cv, &mutex);
277 }
278
279 // Start all threads.
280 for (int n = thread_count - 1; n >= 0; --n) {
281 threads[n]->Start();
282 }
283
284 // Join and cleanup all threads.
285 for (int n = 0; n < thread_count; ++n) {
286 threads[n]->Join();
287 delete threads[n];
288 }
289 delete[] threads;
290
291 EXPECT_EQ(limit, counter);
292 }
293 }
294
295 } // namespace base
296 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698