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

Side by Side Diff: test/cctest/test-condition-variable.cc

Issue 358363002: Move platform abstraction to base library (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: updates Created 6 years, 5 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
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "src/v8.h" 28 #include "src/v8.h"
29 29
30 #include "src/platform/condition-variable.h" 30 #include "src/base/platform/condition-variable.h"
31 #include "src/platform/time.h" 31 #include "src/base/platform/time.h"
32 #include "test/cctest/cctest.h" 32 #include "test/cctest/cctest.h"
33 33
34 using namespace ::v8::internal; 34 using namespace ::v8::internal;
35 35
36 36
37 TEST(WaitForAfterNofityOnSameThread) { 37 TEST(WaitForAfterNofityOnSameThread) {
38 for (int n = 0; n < 10; ++n) { 38 for (int n = 0; n < 10; ++n) {
39 Mutex mutex; 39 v8::base::Mutex mutex;
40 ConditionVariable cv; 40 v8::base::ConditionVariable cv;
41 41
42 LockGuard<Mutex> lock_guard(&mutex); 42 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
43 43
44 cv.NotifyOne(); 44 cv.NotifyOne();
45 CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n))); 45 CHECK_EQ(false,
46 cv.WaitFor(&mutex, v8::base::TimeDelta::FromMicroseconds(n)));
46 47
47 cv.NotifyAll(); 48 cv.NotifyAll();
48 CHECK_EQ(false, cv.WaitFor(&mutex, TimeDelta::FromMicroseconds(n))); 49 CHECK_EQ(false,
50 cv.WaitFor(&mutex, v8::base::TimeDelta::FromMicroseconds(n)));
49 } 51 }
50 } 52 }
51 53
52 54
53 class ThreadWithMutexAndConditionVariable V8_FINAL : public Thread { 55 class ThreadWithMutexAndConditionVariable V8_FINAL : public v8::base::Thread {
54 public: 56 public:
55 ThreadWithMutexAndConditionVariable() 57 ThreadWithMutexAndConditionVariable()
56 : Thread("ThreadWithMutexAndConditionVariable"), 58 : Thread("ThreadWithMutexAndConditionVariable"),
57 running_(false), finished_(false) {} 59 running_(false), finished_(false) {}
58 virtual ~ThreadWithMutexAndConditionVariable() {} 60 virtual ~ThreadWithMutexAndConditionVariable() {}
59 61
60 virtual void Run() V8_OVERRIDE { 62 virtual void Run() V8_OVERRIDE {
61 LockGuard<Mutex> lock_guard(&mutex_); 63 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex_);
62 running_ = true; 64 running_ = true;
63 cv_.NotifyOne(); 65 cv_.NotifyOne();
64 while (running_) { 66 while (running_) {
65 cv_.Wait(&mutex_); 67 cv_.Wait(&mutex_);
66 } 68 }
67 finished_ = true; 69 finished_ = true;
68 cv_.NotifyAll(); 70 cv_.NotifyAll();
69 } 71 }
70 72
71 bool running_; 73 bool running_;
72 bool finished_; 74 bool finished_;
73 ConditionVariable cv_; 75 v8::base::ConditionVariable cv_;
74 Mutex mutex_; 76 v8::base::Mutex mutex_;
75 }; 77 };
76 78
77 79
78 TEST(MultipleThreadsWithSeparateConditionVariables) { 80 TEST(MultipleThreadsWithSeparateConditionVariables) {
79 static const int kThreadCount = 128; 81 static const int kThreadCount = 128;
80 ThreadWithMutexAndConditionVariable threads[kThreadCount]; 82 ThreadWithMutexAndConditionVariable threads[kThreadCount];
81 83
82 for (int n = 0; n < kThreadCount; ++n) { 84 for (int n = 0; n < kThreadCount; ++n) {
83 LockGuard<Mutex> lock_guard(&threads[n].mutex_); 85 v8::base::LockGuard<v8::base::Mutex> lock_guard(&threads[n].mutex_);
84 CHECK(!threads[n].running_); 86 CHECK(!threads[n].running_);
85 CHECK(!threads[n].finished_); 87 CHECK(!threads[n].finished_);
86 threads[n].Start(); 88 threads[n].Start();
87 // Wait for nth thread to start. 89 // Wait for nth thread to start.
88 while (!threads[n].running_) { 90 while (!threads[n].running_) {
89 threads[n].cv_.Wait(&threads[n].mutex_); 91 threads[n].cv_.Wait(&threads[n].mutex_);
90 } 92 }
91 } 93 }
92 94
93 for (int n = kThreadCount - 1; n >= 0; --n) { 95 for (int n = kThreadCount - 1; n >= 0; --n) {
94 LockGuard<Mutex> lock_guard(&threads[n].mutex_); 96 v8::base::LockGuard<v8::base::Mutex> lock_guard(&threads[n].mutex_);
95 CHECK(threads[n].running_); 97 CHECK(threads[n].running_);
96 CHECK(!threads[n].finished_); 98 CHECK(!threads[n].finished_);
97 } 99 }
98 100
99 for (int n = 0; n < kThreadCount; ++n) { 101 for (int n = 0; n < kThreadCount; ++n) {
100 LockGuard<Mutex> lock_guard(&threads[n].mutex_); 102 v8::base::LockGuard<v8::base::Mutex> lock_guard(&threads[n].mutex_);
101 CHECK(threads[n].running_); 103 CHECK(threads[n].running_);
102 CHECK(!threads[n].finished_); 104 CHECK(!threads[n].finished_);
103 // Tell the nth thread to quit. 105 // Tell the nth thread to quit.
104 threads[n].running_ = false; 106 threads[n].running_ = false;
105 threads[n].cv_.NotifyOne(); 107 threads[n].cv_.NotifyOne();
106 } 108 }
107 109
108 for (int n = kThreadCount - 1; n >= 0; --n) { 110 for (int n = kThreadCount - 1; n >= 0; --n) {
109 // Wait for nth thread to quit. 111 // Wait for nth thread to quit.
110 LockGuard<Mutex> lock_guard(&threads[n].mutex_); 112 v8::base::LockGuard<v8::base::Mutex> lock_guard(&threads[n].mutex_);
111 while (!threads[n].finished_) { 113 while (!threads[n].finished_) {
112 threads[n].cv_.Wait(&threads[n].mutex_); 114 threads[n].cv_.Wait(&threads[n].mutex_);
113 } 115 }
114 CHECK(!threads[n].running_); 116 CHECK(!threads[n].running_);
115 CHECK(threads[n].finished_); 117 CHECK(threads[n].finished_);
116 } 118 }
117 119
118 for (int n = 0; n < kThreadCount; ++n) { 120 for (int n = 0; n < kThreadCount; ++n) {
119 threads[n].Join(); 121 threads[n].Join();
120 LockGuard<Mutex> lock_guard(&threads[n].mutex_); 122 v8::base::LockGuard<v8::base::Mutex> lock_guard(&threads[n].mutex_);
121 CHECK(!threads[n].running_); 123 CHECK(!threads[n].running_);
122 CHECK(threads[n].finished_); 124 CHECK(threads[n].finished_);
123 } 125 }
124 } 126 }
125 127
126 128
127 class ThreadWithSharedMutexAndConditionVariable V8_FINAL : public Thread { 129 class ThreadWithSharedMutexAndConditionVariable V8_FINAL
130 : public v8::base::Thread {
128 public: 131 public:
129 ThreadWithSharedMutexAndConditionVariable() 132 ThreadWithSharedMutexAndConditionVariable()
130 : Thread("ThreadWithSharedMutexAndConditionVariable"), 133 : Thread("ThreadWithSharedMutexAndConditionVariable"),
131 running_(false), finished_(false), cv_(NULL), mutex_(NULL) {} 134 running_(false), finished_(false), cv_(NULL), mutex_(NULL) {}
132 virtual ~ThreadWithSharedMutexAndConditionVariable() {} 135 virtual ~ThreadWithSharedMutexAndConditionVariable() {}
133 136
134 virtual void Run() V8_OVERRIDE { 137 virtual void Run() V8_OVERRIDE {
135 LockGuard<Mutex> lock_guard(mutex_); 138 v8::base::LockGuard<v8::base::Mutex> lock_guard(mutex_);
136 running_ = true; 139 running_ = true;
137 cv_->NotifyAll(); 140 cv_->NotifyAll();
138 while (running_) { 141 while (running_) {
139 cv_->Wait(mutex_); 142 cv_->Wait(mutex_);
140 } 143 }
141 finished_ = true; 144 finished_ = true;
142 cv_->NotifyAll(); 145 cv_->NotifyAll();
143 } 146 }
144 147
145 bool running_; 148 bool running_;
146 bool finished_; 149 bool finished_;
147 ConditionVariable* cv_; 150 v8::base::ConditionVariable* cv_;
148 Mutex* mutex_; 151 v8::base::Mutex* mutex_;
149 }; 152 };
150 153
151 154
152 TEST(MultipleThreadsWithSharedSeparateConditionVariables) { 155 TEST(MultipleThreadsWithSharedSeparateConditionVariables) {
153 static const int kThreadCount = 128; 156 static const int kThreadCount = 128;
154 ThreadWithSharedMutexAndConditionVariable threads[kThreadCount]; 157 ThreadWithSharedMutexAndConditionVariable threads[kThreadCount];
155 ConditionVariable cv; 158 v8::base::ConditionVariable cv;
156 Mutex mutex; 159 v8::base::Mutex mutex;
157 160
158 for (int n = 0; n < kThreadCount; ++n) { 161 for (int n = 0; n < kThreadCount; ++n) {
159 threads[n].mutex_ = &mutex; 162 threads[n].mutex_ = &mutex;
160 threads[n].cv_ = &cv; 163 threads[n].cv_ = &cv;
161 } 164 }
162 165
163 // Start all threads. 166 // Start all threads.
164 { 167 {
165 LockGuard<Mutex> lock_guard(&mutex); 168 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
166 for (int n = 0; n < kThreadCount; ++n) { 169 for (int n = 0; n < kThreadCount; ++n) {
167 CHECK(!threads[n].running_); 170 CHECK(!threads[n].running_);
168 CHECK(!threads[n].finished_); 171 CHECK(!threads[n].finished_);
169 threads[n].Start(); 172 threads[n].Start();
170 } 173 }
171 } 174 }
172 175
173 // Wait for all threads to start. 176 // Wait for all threads to start.
174 { 177 {
175 LockGuard<Mutex> lock_guard(&mutex); 178 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
176 for (int n = kThreadCount - 1; n >= 0; --n) { 179 for (int n = kThreadCount - 1; n >= 0; --n) {
177 while (!threads[n].running_) { 180 while (!threads[n].running_) {
178 cv.Wait(&mutex); 181 cv.Wait(&mutex);
179 } 182 }
180 } 183 }
181 } 184 }
182 185
183 // Make sure that all threads are running. 186 // Make sure that all threads are running.
184 { 187 {
185 LockGuard<Mutex> lock_guard(&mutex); 188 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
186 for (int n = 0; n < kThreadCount; ++n) { 189 for (int n = 0; n < kThreadCount; ++n) {
187 CHECK(threads[n].running_); 190 CHECK(threads[n].running_);
188 CHECK(!threads[n].finished_); 191 CHECK(!threads[n].finished_);
189 } 192 }
190 } 193 }
191 194
192 // Tell all threads to quit. 195 // Tell all threads to quit.
193 { 196 {
194 LockGuard<Mutex> lock_guard(&mutex); 197 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
195 for (int n = kThreadCount - 1; n >= 0; --n) { 198 for (int n = kThreadCount - 1; n >= 0; --n) {
196 CHECK(threads[n].running_); 199 CHECK(threads[n].running_);
197 CHECK(!threads[n].finished_); 200 CHECK(!threads[n].finished_);
198 // Tell the nth thread to quit. 201 // Tell the nth thread to quit.
199 threads[n].running_ = false; 202 threads[n].running_ = false;
200 } 203 }
201 cv.NotifyAll(); 204 cv.NotifyAll();
202 } 205 }
203 206
204 // Wait for all threads to quit. 207 // Wait for all threads to quit.
205 { 208 {
206 LockGuard<Mutex> lock_guard(&mutex); 209 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
207 for (int n = 0; n < kThreadCount; ++n) { 210 for (int n = 0; n < kThreadCount; ++n) {
208 while (!threads[n].finished_) { 211 while (!threads[n].finished_) {
209 cv.Wait(&mutex); 212 cv.Wait(&mutex);
210 } 213 }
211 } 214 }
212 } 215 }
213 216
214 // Make sure all threads are finished. 217 // Make sure all threads are finished.
215 { 218 {
216 LockGuard<Mutex> lock_guard(&mutex); 219 v8::base::LockGuard<v8::base::Mutex> lock_guard(&mutex);
217 for (int n = kThreadCount - 1; n >= 0; --n) { 220 for (int n = kThreadCount - 1; n >= 0; --n) {
218 CHECK(!threads[n].running_); 221 CHECK(!threads[n].running_);
219 CHECK(threads[n].finished_); 222 CHECK(threads[n].finished_);
220 } 223 }
221 } 224 }
222 225
223 // Join all threads. 226 // Join all threads.
224 for (int n = 0; n < kThreadCount; ++n) { 227 for (int n = 0; n < kThreadCount; ++n) {
225 threads[n].Join(); 228 threads[n].Join();
226 } 229 }
227 } 230 }
228 231
229 232
230 class LoopIncrementThread V8_FINAL : public Thread { 233 class LoopIncrementThread V8_FINAL : public v8::base::Thread {
231 public: 234 public:
232 LoopIncrementThread(int rem, 235 LoopIncrementThread(int rem,
233 int* counter, 236 int* counter,
234 int limit, 237 int limit,
235 int thread_count, 238 int thread_count,
236 ConditionVariable* cv, 239 v8::base::ConditionVariable* cv,
237 Mutex* mutex) 240 v8::base::Mutex* mutex)
238 : Thread("LoopIncrementThread"), rem_(rem), counter_(counter), 241 : Thread("LoopIncrementThread"), rem_(rem), counter_(counter),
239 limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex) { 242 limit_(limit), thread_count_(thread_count), cv_(cv), mutex_(mutex) {
240 CHECK_LT(rem, thread_count); 243 CHECK_LT(rem, thread_count);
241 CHECK_EQ(0, limit % thread_count); 244 CHECK_EQ(0, limit % thread_count);
242 } 245 }
243 246
244 virtual void Run() V8_OVERRIDE { 247 virtual void Run() V8_OVERRIDE {
245 int last_count = -1; 248 int last_count = -1;
246 while (true) { 249 while (true) {
247 LockGuard<Mutex> lock_guard(mutex_); 250 v8::base::LockGuard<v8::base::Mutex> lock_guard(mutex_);
248 int count = *counter_; 251 int count = *counter_;
249 while (count % thread_count_ != rem_ && count < limit_) { 252 while (count % thread_count_ != rem_ && count < limit_) {
250 cv_->Wait(mutex_); 253 cv_->Wait(mutex_);
251 count = *counter_; 254 count = *counter_;
252 } 255 }
253 if (count >= limit_) break; 256 if (count >= limit_) break;
254 CHECK_EQ(*counter_, count); 257 CHECK_EQ(*counter_, count);
255 if (last_count != -1) { 258 if (last_count != -1) {
256 CHECK_EQ(last_count + (thread_count_ - 1), count); 259 CHECK_EQ(last_count + (thread_count_ - 1), count);
257 } 260 }
258 count++; 261 count++;
259 *counter_ = count; 262 *counter_ = count;
260 last_count = count; 263 last_count = count;
261 cv_->NotifyAll(); 264 cv_->NotifyAll();
262 } 265 }
263 } 266 }
264 267
265 private: 268 private:
266 const int rem_; 269 const int rem_;
267 int* counter_; 270 int* counter_;
268 const int limit_; 271 const int limit_;
269 const int thread_count_; 272 const int thread_count_;
270 ConditionVariable* cv_; 273 v8::base::ConditionVariable* cv_;
271 Mutex* mutex_; 274 v8::base::Mutex* mutex_;
272 }; 275 };
273 276
274 277
275 TEST(LoopIncrement) { 278 TEST(LoopIncrement) {
276 static const int kMaxThreadCount = 16; 279 static const int kMaxThreadCount = 16;
277 Mutex mutex; 280 v8::base::Mutex mutex;
278 ConditionVariable cv; 281 v8::base::ConditionVariable cv;
279 for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) { 282 for (int thread_count = 1; thread_count < kMaxThreadCount; ++thread_count) {
280 int limit = thread_count * 100; 283 int limit = thread_count * 100;
281 int counter = 0; 284 int counter = 0;
282 285
283 // Setup the threads. 286 // Setup the threads.
284 Thread** threads = new Thread*[thread_count]; 287 v8::base::Thread** threads = new v8::base::Thread*[thread_count];
285 for (int n = 0; n < thread_count; ++n) { 288 for (int n = 0; n < thread_count; ++n) {
286 threads[n] = new LoopIncrementThread( 289 threads[n] = new LoopIncrementThread(
287 n, &counter, limit, thread_count, &cv, &mutex); 290 n, &counter, limit, thread_count, &cv, &mutex);
288 } 291 }
289 292
290 // Start all threads. 293 // Start all threads.
291 for (int n = thread_count - 1; n >= 0; --n) { 294 for (int n = thread_count - 1; n >= 0; --n) {
292 threads[n]->Start(); 295 threads[n]->Start();
293 } 296 }
294 297
295 // Join and cleanup all threads. 298 // Join and cleanup all threads.
296 for (int n = 0; n < thread_count; ++n) { 299 for (int n = 0; n < thread_count; ++n) {
297 threads[n]->Join(); 300 threads[n]->Join();
298 delete threads[n]; 301 delete threads[n];
299 } 302 }
300 delete[] threads; 303 delete[] threads;
301 304
302 CHECK_EQ(limit, counter); 305 CHECK_EQ(limit, counter);
303 } 306 }
304 } 307 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698