OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Multi-threaded tests of ConditionVariable class. | 5 // Multi-threaded tests of ConditionVariable class. |
6 | 6 |
7 #include <time.h> | 7 #include <time.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
| 11 #include "base/bind.h" |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
13 #include "base/synchronization/condition_variable.h" | 14 #include "base/synchronization/condition_variable.h" |
14 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
15 #include "base/synchronization/spin_wait.h" | 16 #include "base/synchronization/spin_wait.h" |
16 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
| 18 #include "base/threading/thread.h" |
17 #include "base/threading/thread_collision_warner.h" | 19 #include "base/threading/thread_collision_warner.h" |
18 #include "base/time/time.h" | 20 #include "base/time/time.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "testing/platform_test.h" | 22 #include "testing/platform_test.h" |
21 | 23 |
22 namespace base { | 24 namespace base { |
23 | 25 |
24 namespace { | 26 namespace { |
25 //------------------------------------------------------------------------------ | 27 //------------------------------------------------------------------------------ |
26 // Define our test class, with several common variables. | 28 // Define our test class, with several common variables. |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 183 |
182 cv.TimedWait(WAIT_TIME + FUDGE_TIME); | 184 cv.TimedWait(WAIT_TIME + FUDGE_TIME); |
183 TimeDelta duration = TimeTicks::Now() - start; | 185 TimeDelta duration = TimeTicks::Now() - start; |
184 // We can't use EXPECT_GE here as the TimeDelta class does not support the | 186 // We can't use EXPECT_GE here as the TimeDelta class does not support the |
185 // required stream conversion. | 187 // required stream conversion. |
186 EXPECT_TRUE(duration >= WAIT_TIME); | 188 EXPECT_TRUE(duration >= WAIT_TIME); |
187 | 189 |
188 lock.Release(); | 190 lock.Release(); |
189 } | 191 } |
190 | 192 |
| 193 #if defined(OS_POSIX) |
| 194 const int kDiscontinuitySeconds = 2; |
| 195 |
| 196 void BackInTime(Lock* lock) { |
| 197 AutoLock auto_lock(*lock); |
| 198 |
| 199 timeval tv; |
| 200 gettimeofday(&tv, NULL); |
| 201 tv.tv_sec -= kDiscontinuitySeconds; |
| 202 settimeofday(&tv, NULL); |
| 203 } |
| 204 |
| 205 // Tests that TimedWait ignores changes to the system clock. |
| 206 // Test is disabled by default, because it needs to run as root to muck with the |
| 207 // system clock. |
| 208 // This currently works on Linux and Android but will fail on Mac. |
| 209 // http://crbug.com/293736 |
| 210 TEST_F(ConditionVariableTest, DISABLED_TimeoutAcrossSetTimeOfDay) { |
| 211 timeval tv; |
| 212 gettimeofday(&tv, NULL); |
| 213 tv.tv_sec += kDiscontinuitySeconds; |
| 214 if (settimeofday(&tv, NULL) < 0) { |
| 215 PLOG(ERROR) << "Could not set time of day. Run as root?"; |
| 216 return; |
| 217 } |
| 218 |
| 219 Lock lock; |
| 220 ConditionVariable cv(&lock); |
| 221 lock.Acquire(); |
| 222 |
| 223 Thread thread("Helper"); |
| 224 thread.Start(); |
| 225 thread.message_loop()->PostTask(FROM_HERE, base::Bind(&BackInTime, &lock)); |
| 226 |
| 227 TimeTicks start = TimeTicks::Now(); |
| 228 const TimeDelta kWaitTime = TimeDelta::FromMilliseconds(300); |
| 229 // Allow for clocking rate granularity. |
| 230 const TimeDelta kFudgeTime = TimeDelta::FromMilliseconds(50); |
| 231 |
| 232 cv.TimedWait(kWaitTime + kFudgeTime); |
| 233 TimeDelta duration = TimeTicks::Now() - start; |
| 234 |
| 235 thread.Stop(); |
| 236 // We can't use EXPECT_GE here as the TimeDelta class does not support the |
| 237 // required stream conversion. |
| 238 EXPECT_TRUE(duration >= kWaitTime); |
| 239 EXPECT_TRUE(duration <= TimeDelta::FromSeconds(kDiscontinuitySeconds)); |
| 240 |
| 241 lock.Release(); |
| 242 } |
| 243 #endif |
| 244 |
191 | 245 |
192 // Suddenly got flaky on Win, see http://crbug.com/10607 (starting at | 246 // Suddenly got flaky on Win, see http://crbug.com/10607 (starting at |
193 // comment #15) | 247 // comment #15) |
194 #if defined(OS_WIN) | 248 #if defined(OS_WIN) |
195 #define MAYBE_MultiThreadConsumerTest DISABLED_MultiThreadConsumerTest | 249 #define MAYBE_MultiThreadConsumerTest DISABLED_MultiThreadConsumerTest |
196 #else | 250 #else |
197 #define MAYBE_MultiThreadConsumerTest MultiThreadConsumerTest | 251 #define MAYBE_MultiThreadConsumerTest MultiThreadConsumerTest |
198 #endif | 252 #endif |
199 // Test serial task servicing, as well as two parallel task servicing methods. | 253 // Test serial task servicing, as well as two parallel task servicing methods. |
200 TEST_F(ConditionVariableTest, MAYBE_MultiThreadConsumerTest) { | 254 TEST_F(ConditionVariableTest, MAYBE_MultiThreadConsumerTest) { |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 base::AutoLock auto_lock(lock_); | 760 base::AutoLock auto_lock(lock_); |
707 // Send notification that we completed our "work." | 761 // Send notification that we completed our "work." |
708 WorkIsCompleted(thread_id); | 762 WorkIsCompleted(thread_id); |
709 } | 763 } |
710 } | 764 } |
711 } | 765 } |
712 | 766 |
713 } // namespace | 767 } // namespace |
714 | 768 |
715 } // namespace base | 769 } // namespace base |
OLD | NEW |