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

Side by Side Diff: base/thread_collision_warner_unittest.cc

Issue 6258: This CL is due the thread I have made on chromium-dev:... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 12 years, 2 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
« no previous file with comments | « base/thread_collision_warner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2008 The Chromium 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 "base/lock.h"
6 #include "base/platform_thread.h"
7 #include "base/simple_thread.h"
8 #include "base/thread_collision_warner.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11
12 namespace {
13
14 // This is the asserter used with ThreadCollisionWarner instead of the default
15 // DCheckAsserter. The method fail_state is used to know if a collision took
16 // place.
17 class AssertReporter : public base::AsserterBase {
18 public:
19 AssertReporter()
20 : failed_(false) {}
21
22 virtual void warn() {
23 failed_ = true;
24 }
25
26 virtual ~AssertReporter() {}
27
28 bool fail_state() const { return failed_; }
29 void reset() { failed_ = false; }
30
31 private:
32 bool failed_;
33 };
34
35 } // namespace
36
37 TEST(ThreadCollisionTest, BookCriticalSection) {
38 AssertReporter* local_reporter = new AssertReporter();
39
40 base::ThreadCollisionWarner warner(local_reporter);
41 EXPECT_FALSE(local_reporter->fail_state());
42
43 { // Pin section.
44 D_BOOK_CRITICAL_SECTION(warner);
45 EXPECT_FALSE(local_reporter->fail_state());
46 { // Pin section.
47 D_BOOK_CRITICAL_SECTION(warner);
48 EXPECT_FALSE(local_reporter->fail_state());
49 }
50 }
51 }
52
53 TEST(ThreadCollisionTest, ScopedRecursiveBookCriticalSection) {
54 AssertReporter* local_reporter = new AssertReporter();
55
56 base::ThreadCollisionWarner warner(local_reporter);
57 EXPECT_FALSE(local_reporter->fail_state());
58
59 { // Pin section.
60 D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION(warner);
61 EXPECT_FALSE(local_reporter->fail_state());
62 { // Pin section again (allowed by D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION )
63 D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION(warner);
64 EXPECT_FALSE(local_reporter->fail_state());
65 } // Unpin section.
66 } // Unpin section.
67
68 // Check that section is not pinned
69 { // Pin section.
70 D_SCOPED_BOOK_CRITICAL_SECTION(warner);
71 EXPECT_FALSE(local_reporter->fail_state());
72 } // Unpin section.
73 }
74
75 TEST(ThreadCollisionTest, ScopedBookCriticalSection) {
76 AssertReporter* local_reporter = new AssertReporter();
77
78 base::ThreadCollisionWarner warner(local_reporter);
79 EXPECT_FALSE(local_reporter->fail_state());
80
81 { // Pin section.
82 D_SCOPED_BOOK_CRITICAL_SECTION(warner);
83 EXPECT_FALSE(local_reporter->fail_state());
84 } // Unpin section.
85
86 { // Pin section.
87 D_SCOPED_BOOK_CRITICAL_SECTION(warner);
88 EXPECT_FALSE(local_reporter->fail_state());
89 { // Pin section again (not allowed by D_SCOPED_BOOK_CRITICAL_SECTION)
90 D_SCOPED_BOOK_CRITICAL_SECTION(warner);
91 EXPECT_TRUE(local_reporter->fail_state());
92 // Reset the status of warner for further tests.
93 local_reporter->reset();
94 } // Unpin section.
95 } // Unpin section.
96
97 { // Pin section.
98 D_SCOPED_BOOK_CRITICAL_SECTION(warner);
99 EXPECT_FALSE(local_reporter->fail_state());
100 } // Unpin section.
101
102 }
103
104 TEST(ThreadCollisionTest, MTBookCriticalSectionTest) {
105 class NonThreadSafeQueue {
106 public:
107 NonThreadSafeQueue(base::AsserterBase* asserter)
108 : push_pop_(asserter) { }
109
110 void push(int) {
111 D_BOOK_CRITICAL_SECTION(push_pop_);
112 }
113
114 int pop() {
115 D_BOOK_CRITICAL_SECTION(push_pop_);
116 return 0;
117 }
118
119 private:
120 base::ThreadCollisionWarner push_pop_;
121
122 DISALLOW_COPY_AND_ASSIGN(NonThreadSafeQueue);
123 };
124
125 class QueueUser : public base::DelegateSimpleThread::Delegate {
126 public:
127 QueueUser(NonThreadSafeQueue& queue)
128 : queue_(queue) {}
129
130 virtual void Run() {
131 queue_.push(0);
132 queue_.pop();
133 }
134
135 private:
136 NonThreadSafeQueue& queue_;
137 };
138
139 AssertReporter* local_reporter = new AssertReporter();
140
141 NonThreadSafeQueue queue(local_reporter);
142
143 QueueUser queue_user_a(queue);
144 QueueUser queue_user_b(queue);
145
146 base::DelegateSimpleThread thread_a(&queue_user_a, "queue_user_thread_a");
147 base::DelegateSimpleThread thread_b(&queue_user_b, "queue_user_thread_b");
148
149 thread_a.Start();
150 thread_b.Start();
151
152 thread_a.Join();
153 thread_b.Join();
154
155 EXPECT_TRUE(local_reporter->fail_state());
156 }
157
158 TEST(ThreadCollisionTest, MTScopedBookCriticalSectionTest) {
159
160 // Queue with a 5 seconds push execution time, hopefuly the two used threads
161 // in the test will enter the push at same time.
162 class NonThreadSafeQueue {
163 public:
164 NonThreadSafeQueue(base::AsserterBase* asserter)
165 : push_pop_(asserter) { }
166
167 void push(int) {
168 D_SCOPED_BOOK_CRITICAL_SECTION(push_pop_);
169 PlatformThread::Sleep(5000);
170 }
171
172 int pop() {
173 D_SCOPED_BOOK_CRITICAL_SECTION(push_pop_);
174 return 0;
175 }
176
177 private:
178 base::ThreadCollisionWarner push_pop_;
179
180 DISALLOW_COPY_AND_ASSIGN(NonThreadSafeQueue);
181 };
182
183 class QueueUser : public base::DelegateSimpleThread::Delegate {
184 public:
185 QueueUser(NonThreadSafeQueue& queue)
186 : queue_(queue) {}
187
188 virtual void Run() {
189 queue_.push(0);
190 queue_.pop();
191 }
192
193 private:
194 NonThreadSafeQueue& queue_;
195 };
196
197 AssertReporter* local_reporter = new AssertReporter();
198
199 NonThreadSafeQueue queue(local_reporter);
200
201 QueueUser queue_user_a(queue);
202 QueueUser queue_user_b(queue);
203
204 base::DelegateSimpleThread thread_a(&queue_user_a, "queue_user_thread_a");
205 base::DelegateSimpleThread thread_b(&queue_user_b, "queue_user_thread_b");
206
207 thread_a.Start();
208 thread_b.Start();
209
210 thread_a.Join();
211 thread_b.Join();
212
213 EXPECT_TRUE(local_reporter->fail_state());
214 }
215
216 TEST(ThreadCollisionTest, MTSynchedScopedBookCriticalSectionTest) {
217
218 // Queue with a 5 seconds push execution time, hopefuly the two used threads
219 // in the test will enter the push at same time.
220 class NonThreadSafeQueue {
221 public:
222 NonThreadSafeQueue(base::AsserterBase* asserter)
223 : push_pop_(asserter) { }
224
225 void push(int) {
226 D_SCOPED_BOOK_CRITICAL_SECTION(push_pop_);
227 PlatformThread::Sleep(5000);
228 }
229
230 int pop() {
231 D_SCOPED_BOOK_CRITICAL_SECTION(push_pop_);
232 return 0;
233 }
234
235 private:
236 base::ThreadCollisionWarner push_pop_;
237
238 DISALLOW_COPY_AND_ASSIGN(NonThreadSafeQueue);
239 };
240
241 // This time the QueueUser class protects the non thread safe queue with
242 // a lock.
243 class QueueUser : public base::DelegateSimpleThread::Delegate {
244 public:
245 QueueUser(NonThreadSafeQueue& queue, Lock& lock)
246 : queue_(queue),
247 lock_(lock) {}
248
249 virtual void Run() {
250 {
251 AutoLock auto_lock(lock_);
252 queue_.push(0);
253 }
254 {
255 AutoLock auto_lock(lock_);
256 queue_.pop();
257 }
258 }
259 private:
260 NonThreadSafeQueue& queue_;
261 Lock& lock_;
262 };
263
264 AssertReporter* local_reporter = new AssertReporter();
265
266 NonThreadSafeQueue queue(local_reporter);
267
268 Lock lock;
269
270 QueueUser queue_user_a(queue, lock);
271 QueueUser queue_user_b(queue, lock);
272
273 base::DelegateSimpleThread thread_a(&queue_user_a, "queue_user_thread_a");
274 base::DelegateSimpleThread thread_b(&queue_user_b, "queue_user_thread_b");
275
276 thread_a.Start();
277 thread_b.Start();
278
279 thread_a.Join();
280 thread_b.Join();
281
282 EXPECT_FALSE(local_reporter->fail_state());
283 }
284
285 TEST(ThreadCollisionTest, MTSynchedScopedRecursiveBookCriticalSectionTest) {
286
287 // Queue with a 5 seconds push execution time, hopefuly the two used threads
288 // in the test will enter the push at same time.
289 class NonThreadSafeQueue {
290 public:
291 NonThreadSafeQueue(base::AsserterBase* asserter)
292 : push_pop_(asserter) { }
293
294 void push(int) {
295 D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION(push_pop_);
296 bar();
297 PlatformThread::Sleep(5000);
298 }
299
300 int pop() {
301 D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION(push_pop_);
302 return 0;
303 }
304
305 void bar() {
306 D_SCOPED_RECURSIVE_BOOK_CRITICAL_SECTION(push_pop_);
307 }
308
309 private:
310 base::ThreadCollisionWarner push_pop_;
311
312 DISALLOW_COPY_AND_ASSIGN(NonThreadSafeQueue);
313 };
314
315 // This time the QueueUser class protects the non thread safe queue with
316 // a lock.
317 class QueueUser : public base::DelegateSimpleThread::Delegate {
318 public:
319 QueueUser(NonThreadSafeQueue& queue, Lock& lock)
320 : queue_(queue),
321 lock_(lock) {}
322
323 virtual void Run() {
324 {
325 AutoLock auto_lock(lock_);
326 queue_.push(0);
327 }
328 {
329 AutoLock auto_lock(lock_);
330 queue_.bar();
331 }
332 {
333 AutoLock auto_lock(lock_);
334 queue_.pop();
335 }
336 }
337 private:
338 NonThreadSafeQueue& queue_;
339 Lock& lock_;
340 };
341
342 AssertReporter* local_reporter = new AssertReporter();
343
344 NonThreadSafeQueue queue(local_reporter);
345
346 Lock lock;
347
348 QueueUser queue_user_a(queue, lock);
349 QueueUser queue_user_b(queue, lock);
350
351 base::DelegateSimpleThread thread_a(&queue_user_a, "queue_user_thread_a");
352 base::DelegateSimpleThread thread_b(&queue_user_b, "queue_user_thread_b");
353
354 thread_a.Start();
355 thread_b.Start();
356
357 thread_a.Join();
358 thread_b.Join();
359
360 EXPECT_FALSE(local_reporter->fail_state());
361 }
362
OLDNEW
« no previous file with comments | « base/thread_collision_warner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698