| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/condition_variable.h" | 11 #include "base/condition_variable.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/platform_thread.h" | 13 #include "base/platform_thread.h" |
| 14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
| 15 #include "base/spin_wait.h" | 15 #include "base/spin_wait.h" |
| 16 #include "base/thread_collision_warner.h" | 16 #include "base/thread_collision_warner.h" |
| 17 #include "base/time.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "testing/platform_test.h" | 19 #include "testing/platform_test.h" |
| 19 | 20 |
| 20 using base::TimeDelta; | 21 using base::TimeDelta; |
| 21 using base::TimeTicks; | 22 using base::TimeTicks; |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 //------------------------------------------------------------------------------ | 25 //------------------------------------------------------------------------------ |
| 25 // Define our test class, with several common variables. | 26 // Define our test class, with several common variables. |
| 26 //------------------------------------------------------------------------------ | 27 //------------------------------------------------------------------------------ |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 | 92 |
| 92 //---------------------------------------------------------------------------- | 93 //---------------------------------------------------------------------------- |
| 93 // The rest of the methods are for use by the controlling master thread (the | 94 // The rest of the methods are for use by the controlling master thread (the |
| 94 // test case code). | 95 // test case code). |
| 95 void ResetHistory(); | 96 void ResetHistory(); |
| 96 int GetMinCompletionsByWorkerThread() const; | 97 int GetMinCompletionsByWorkerThread() const; |
| 97 int GetMaxCompletionsByWorkerThread() const; | 98 int GetMaxCompletionsByWorkerThread() const; |
| 98 int GetNumThreadsTakingAssignments() const; | 99 int GetNumThreadsTakingAssignments() const; |
| 99 int GetNumThreadsCompletingTasks() const; | 100 int GetNumThreadsCompletingTasks() const; |
| 100 int GetNumberOfCompletedTasks() const; | 101 int GetNumberOfCompletedTasks() const; |
| 102 TimeDelta GetWorkTime() const; |
| 101 | 103 |
| 102 void SetWorkTime(TimeDelta delay); | 104 void SetWorkTime(TimeDelta delay); |
| 103 void SetTaskCount(int count); | 105 void SetTaskCount(int count); |
| 104 void SetAllowHelp(bool allow); | 106 void SetAllowHelp(bool allow); |
| 105 | 107 |
| 106 // Caller must acquire lock before calling. | 108 // Caller must acquire lock before calling. |
| 107 void SetShutdown(); | 109 void SetShutdown(); |
| 108 | 110 |
| 109 // Compares the |shutdown_task_count_| to the |thread_count| and returns true | 111 // Compares the |shutdown_task_count_| to the |thread_count| and returns true |
| 110 // if they are equal. This check will acquire the |lock_| so the caller | 112 // if they are equal. This check will acquire the |lock_| so the caller |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 175 |
| 174 cv.TimedWait(WAIT_TIME + FUDGE_TIME); | 176 cv.TimedWait(WAIT_TIME + FUDGE_TIME); |
| 175 TimeDelta duration = TimeTicks::Now() - start; | 177 TimeDelta duration = TimeTicks::Now() - start; |
| 176 // We can't use EXPECT_GE here as the TimeDelta class does not support the | 178 // We can't use EXPECT_GE here as the TimeDelta class does not support the |
| 177 // required stream conversion. | 179 // required stream conversion. |
| 178 EXPECT_TRUE(duration >= WAIT_TIME); | 180 EXPECT_TRUE(duration >= WAIT_TIME); |
| 179 | 181 |
| 180 lock.Release(); | 182 lock.Release(); |
| 181 } | 183 } |
| 182 | 184 |
| 183 // This test is flaky due to excessive timing sensitivity. | 185 // Test serial task servicing, as well as two parallel task servicing methods. |
| 184 // http://code.google.com/p/chromium/issues/detail?id=3599 | 186 TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { |
| 185 // TODO(jar): A recent change to the WorkQueue fixed flakyness for the test | |
| 186 // LargeFastTaskTest. Specifically, the test was accessing the member variable | |
| 187 // WorkQueue::shutdown_task_count_ without a lock held. The MultiThreadConsumer | |
| 188 // test now ran successfully for 500 times on RalphL's machine. RalphL did not | |
| 189 // want to blindly re-enable this test if you know of other issues with it, but | |
| 190 // it appears that the flakyness is gone, but I'll leave that to you to verify. | |
| 191 TEST_F(ConditionVariableTest, DISABLED_MultiThreadConsumerTest) { | |
| 192 const int kThreadCount = 10; | 187 const int kThreadCount = 10; |
| 193 WorkQueue queue(kThreadCount); // Start the threads. | 188 WorkQueue queue(kThreadCount); // Start the threads. |
| 194 | 189 |
| 195 Lock private_lock; // Used locally for master to wait. | 190 const int kTaskCount = 10; // Number of tasks in each mini-test here. |
| 196 AutoLock private_held_lock(private_lock); | 191 |
| 197 ConditionVariable private_cv(&private_lock); | 192 base::Time start_time; // Used to time task processing. |
| 198 | 193 |
| 199 { | 194 { |
| 200 AutoLock auto_lock(*queue.lock()); | 195 AutoLock auto_lock(*queue.lock()); |
| 201 while (!queue.EveryIdWasAllocated()) | 196 while (!queue.EveryIdWasAllocated()) |
| 202 queue.all_threads_have_ids()->Wait(); | 197 queue.all_threads_have_ids()->Wait(); |
| 203 } | 198 } |
| 204 | 199 |
| 205 // Wait a bit more to allow threads to reach their wait state. | 200 // Wait a bit more to allow threads to reach their wait state. |
| 206 private_cv.TimedWait(kTenMs); | 201 // If threads aren't in a wait state, they may start to gobble up tasks in |
| 202 // parallel, short-circuiting (breaking) this test. |
| 203 PlatformThread::Sleep(100); |
| 207 | 204 |
| 208 { | 205 { |
| 209 // Since we have no tasks, all threads should be waiting by now. | 206 // Since we have no tasks yet, all threads should be waiting by now. |
| 210 AutoLock auto_lock(*queue.lock()); | 207 AutoLock auto_lock(*queue.lock()); |
| 211 EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments()); | 208 EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments()); |
| 212 EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks()); | 209 EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks()); |
| 213 EXPECT_EQ(0, queue.task_count()); | 210 EXPECT_EQ(0, queue.task_count()); |
| 214 EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread()); | 211 EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread()); |
| 215 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 212 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
| 216 EXPECT_EQ(0, queue.GetNumberOfCompletedTasks()); | 213 EXPECT_EQ(0, queue.GetNumberOfCompletedTasks()); |
| 217 | 214 |
| 218 // Set up to make one worker do 3 30ms tasks. | 215 // Set up to make one worker do 30ms tasks sequentially. |
| 219 queue.ResetHistory(); | 216 queue.ResetHistory(); |
| 220 queue.SetTaskCount(3); | 217 queue.SetTaskCount(kTaskCount); |
| 221 queue.SetWorkTime(kThirtyMs); | 218 queue.SetWorkTime(kThirtyMs); |
| 222 queue.SetAllowHelp(false); | 219 queue.SetAllowHelp(false); |
| 220 |
| 221 start_time = base::Time::Now(); |
| 223 } | 222 } |
| 223 |
| 224 queue.work_is_available()->Signal(); // Start up one thread. | 224 queue.work_is_available()->Signal(); // Start up one thread. |
| 225 // Wait to allow solo worker insufficient time to get done. | 225 |
| 226 private_cv.TimedWait(kFortyFiveMs); // Should take about 90 ms. | |
| 227 | 226 |
| 228 { | 227 { |
| 229 // Check that all work HASN'T completed yet. | 228 // Wait until all 10 work tasks have at least been assigned. |
| 230 AutoLock auto_lock(*queue.lock()); | 229 AutoLock auto_lock(*queue.lock()); |
| 230 while(queue.task_count()) |
| 231 queue.no_more_tasks()->Wait(); |
| 232 // The last of the tasks *might* still be running, but... all but one should |
| 233 // be done by now, since tasks are being done serially. |
| 234 EXPECT_LT(queue.GetWorkTime().InMilliseconds() * (kTaskCount - 1), |
| 235 (base::Time::Now() - start_time).InMilliseconds()); |
| 236 |
| 231 EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments()); | 237 EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments()); |
| 232 EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks()); | 238 EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks()); |
| 233 EXPECT_GT(2, queue.task_count()); // 2 should have started. | 239 EXPECT_LE(kTaskCount - 1, queue.GetMaxCompletionsByWorkerThread()); |
| 234 EXPECT_GT(3, queue.GetMaxCompletionsByWorkerThread()); | |
| 235 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 240 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
| 236 EXPECT_EQ(1, queue.GetNumberOfCompletedTasks()); | 241 EXPECT_LE(kTaskCount - 1, queue.GetNumberOfCompletedTasks()); |
| 237 } | 242 } |
| 238 // Wait to allow solo workers to get done. | 243 |
| 239 private_cv.TimedWait(kSixtyMs); // Should take about 45ms more. | 244 // Wait to be sure all tasks are done. |
| 245 while (1) { |
| 246 { |
| 247 AutoLock auto_lock(*queue.lock()); |
| 248 if (kTaskCount == queue.GetNumberOfCompletedTasks()) |
| 249 break; |
| 250 } |
| 251 PlatformThread::Sleep(30); // Wait a little. |
| 252 } |
| 240 | 253 |
| 241 { | 254 { |
| 242 // Check that all work was done by one thread id. | 255 // Check that all work was done by one thread id. |
| 243 AutoLock auto_lock(*queue.lock()); | 256 AutoLock auto_lock(*queue.lock()); |
| 244 EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments()); | 257 EXPECT_EQ(1, queue.GetNumThreadsTakingAssignments()); |
| 245 EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks()); | 258 EXPECT_EQ(1, queue.GetNumThreadsCompletingTasks()); |
| 246 EXPECT_EQ(0, queue.task_count()); | 259 EXPECT_EQ(0, queue.task_count()); |
| 247 EXPECT_EQ(3, queue.GetMaxCompletionsByWorkerThread()); | 260 EXPECT_EQ(kTaskCount, queue.GetMaxCompletionsByWorkerThread()); |
| 248 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 261 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
| 249 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); | 262 EXPECT_EQ(kTaskCount, queue.GetNumberOfCompletedTasks()); |
| 250 | 263 |
| 251 // Set up to make each task include getting help from another worker. | 264 // Set up to make each task include getting help from another worker, so |
| 265 // so that the work gets done in paralell. |
| 252 queue.ResetHistory(); | 266 queue.ResetHistory(); |
| 253 queue.SetTaskCount(3); | 267 queue.SetTaskCount(kTaskCount); |
| 254 queue.SetWorkTime(kThirtyMs); | 268 queue.SetWorkTime(kThirtyMs); |
| 255 queue.SetAllowHelp(true); | 269 queue.SetAllowHelp(true); |
| 270 |
| 271 start_time = base::Time::Now(); |
| 256 } | 272 } |
| 273 |
| 257 queue.work_is_available()->Signal(); // But each worker can signal another. | 274 queue.work_is_available()->Signal(); // But each worker can signal another. |
| 258 // Wait to allow the 3 workers to get done. | 275 // Wait to allow the all workers to get done. |
| 259 private_cv.TimedWait(kFortyFiveMs); // Should take about 30 ms. | 276 while (1) { |
| 277 { |
| 278 AutoLock auto_lock(*queue.lock()); |
| 279 if (kTaskCount == queue.GetNumberOfCompletedTasks()) |
| 280 break; |
| 281 } |
| 282 PlatformThread::Sleep(30); // Wait a little. |
| 283 } |
| 260 | 284 |
| 261 { | 285 { |
| 286 // Wait until all work tasks have at least been assigned. |
| 262 AutoLock auto_lock(*queue.lock()); | 287 AutoLock auto_lock(*queue.lock()); |
| 263 EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); | 288 while(queue.task_count()) |
| 264 EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); | 289 queue.no_more_tasks()->Wait(); |
| 265 EXPECT_EQ(0, queue.task_count()); | 290 // Since they can all run almost in parallel, there is no guarantee that all |
| 266 EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); | 291 // tasks are finished, but we should have gotten here faster than it would |
| 267 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 292 // take to run all tasks serially. |
| 268 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); | 293 EXPECT_GT(queue.GetWorkTime().InMilliseconds() * (kTaskCount - 1), |
| 294 (base::Time::Now() - start_time).InMilliseconds()); |
| 295 |
| 296 // To avoid racy assumptions, we'll just assert that at least 2 threads |
| 297 // did work. |
| 298 EXPECT_LE(2, queue.GetNumThreadsTakingAssignments()); |
| 299 EXPECT_EQ(kTaskCount, queue.GetNumberOfCompletedTasks()); |
| 269 | 300 |
| 270 // Try to ask all workers to help, and only a few will do the work. | 301 // Try to ask all workers to help, and only a few will do the work. |
| 271 queue.ResetHistory(); | 302 queue.ResetHistory(); |
| 272 queue.SetTaskCount(3); | 303 queue.SetTaskCount(3); |
| 273 queue.SetWorkTime(kThirtyMs); | 304 queue.SetWorkTime(kThirtyMs); |
| 274 queue.SetAllowHelp(false); | 305 queue.SetAllowHelp(false); |
| 275 } | 306 } |
| 276 queue.work_is_available()->Broadcast(); // Make them all try. | 307 queue.work_is_available()->Broadcast(); // Make them all try. |
| 277 // Wait to allow the 3 workers to get done. | 308 // Wait to allow the 3 workers to get done. |
| 278 private_cv.TimedWait(kFortyFiveMs); | 309 PlatformThread::Sleep(45); |
| 279 | 310 |
| 280 { | 311 { |
| 281 AutoLock auto_lock(*queue.lock()); | 312 AutoLock auto_lock(*queue.lock()); |
| 282 EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); | 313 EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
| 283 EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); | 314 EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
| 284 EXPECT_EQ(0, queue.task_count()); | 315 EXPECT_EQ(0, queue.task_count()); |
| 285 EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); | 316 EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
| 286 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 317 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
| 287 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); | 318 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
| 288 | 319 |
| 289 // Set up to make each task get help from another worker. | 320 // Set up to make each task get help from another worker. |
| 290 queue.ResetHistory(); | 321 queue.ResetHistory(); |
| 291 queue.SetTaskCount(3); | 322 queue.SetTaskCount(3); |
| 292 queue.SetWorkTime(kThirtyMs); | 323 queue.SetWorkTime(kThirtyMs); |
| 293 queue.SetAllowHelp(true); // Allow (unnecessary) help requests. | 324 queue.SetAllowHelp(true); // Allow (unnecessary) help requests. |
| 294 } | 325 } |
| 295 queue.work_is_available()->Broadcast(); // We already signal all threads. | 326 queue.work_is_available()->Broadcast(); // We already signal all threads. |
| 296 // Wait to allow the 3 workers to get done. | 327 // Wait to allow the 3 workers to get done. |
| 297 private_cv.TimedWait(kOneHundredMs); | 328 PlatformThread::Sleep(100); |
| 298 | 329 |
| 299 { | 330 { |
| 300 AutoLock auto_lock(*queue.lock()); | 331 AutoLock auto_lock(*queue.lock()); |
| 301 EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); | 332 EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
| 302 EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); | 333 EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
| 303 EXPECT_EQ(0, queue.task_count()); | 334 EXPECT_EQ(0, queue.task_count()); |
| 304 EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); | 335 EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
| 305 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); | 336 EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
| 306 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); | 337 EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
| 307 | 338 |
| 308 // Set up to make each task get help from another worker. | 339 // Set up to make each task get help from another worker. |
| 309 queue.ResetHistory(); | 340 queue.ResetHistory(); |
| 310 queue.SetTaskCount(20); | 341 queue.SetTaskCount(20); |
| 311 queue.SetWorkTime(kThirtyMs); | 342 queue.SetWorkTime(kThirtyMs); |
| 312 queue.SetAllowHelp(true); | 343 queue.SetAllowHelp(true); |
| 313 } | 344 } |
| 314 queue.work_is_available()->Signal(); // But each worker can signal another. | 345 queue.work_is_available()->Signal(); // But each worker can signal another. |
| 315 // Wait to allow the 10 workers to get done. | 346 // Wait to allow the 10 workers to get done. |
| 316 private_cv.TimedWait(kOneHundredMs); // Should take about 60 ms. | 347 PlatformThread::Sleep(100); // Should take about 60 ms. |
| 317 | 348 |
| 318 { | 349 { |
| 319 AutoLock auto_lock(*queue.lock()); | 350 AutoLock auto_lock(*queue.lock()); |
| 320 EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); | 351 EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
| 321 EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); | 352 EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
| 322 EXPECT_EQ(0, queue.task_count()); | 353 EXPECT_EQ(0, queue.task_count()); |
| 323 EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread()); | 354 EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread()); |
| 324 EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread()); | 355 EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread()); |
| 325 EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); | 356 EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
| 326 | 357 |
| 327 // Same as last test, but with Broadcast(). | 358 // Same as last test, but with Broadcast(). |
| 328 queue.ResetHistory(); | 359 queue.ResetHistory(); |
| 329 queue.SetTaskCount(20); // 2 tasks per process. | 360 queue.SetTaskCount(20); // 2 tasks per process. |
| 330 queue.SetWorkTime(kThirtyMs); | 361 queue.SetWorkTime(kThirtyMs); |
| 331 queue.SetAllowHelp(true); | 362 queue.SetAllowHelp(true); |
| 332 } | 363 } |
| 333 queue.work_is_available()->Broadcast(); | 364 queue.work_is_available()->Broadcast(); |
| 334 // Wait to allow the 10 workers to get done. | 365 // Wait to allow the 10 workers to get done. |
| 335 private_cv.TimedWait(kOneHundredMs); // Should take about 60 ms. | 366 PlatformThread::Sleep(100); // Should take about 60 ms. |
| 336 | 367 |
| 337 { | 368 { |
| 338 AutoLock auto_lock(*queue.lock()); | 369 AutoLock auto_lock(*queue.lock()); |
| 339 EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); | 370 EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
| 340 EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); | 371 EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
| 341 EXPECT_EQ(0, queue.task_count()); | 372 EXPECT_EQ(0, queue.task_count()); |
| 342 EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread()); | 373 EXPECT_EQ(2, queue.GetMaxCompletionsByWorkerThread()); |
| 343 EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread()); | 374 EXPECT_EQ(2, queue.GetMinCompletionsByWorkerThread()); |
| 344 EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); | 375 EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
| 345 | 376 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 return count; | 640 return count; |
| 610 } | 641 } |
| 611 | 642 |
| 612 int WorkQueue::GetNumberOfCompletedTasks() const { | 643 int WorkQueue::GetNumberOfCompletedTasks() const { |
| 613 int total = 0; | 644 int total = 0; |
| 614 for (int i = 0; i < thread_count_; ++i) | 645 for (int i = 0; i < thread_count_; ++i) |
| 615 total += completion_history_[i]; | 646 total += completion_history_[i]; |
| 616 return total; | 647 return total; |
| 617 } | 648 } |
| 618 | 649 |
| 650 TimeDelta WorkQueue::GetWorkTime() const { |
| 651 return worker_delay_; |
| 652 } |
| 653 |
| 619 void WorkQueue::SetWorkTime(TimeDelta delay) { | 654 void WorkQueue::SetWorkTime(TimeDelta delay) { |
| 620 worker_delay_ = delay; | 655 worker_delay_ = delay; |
| 621 } | 656 } |
| 622 | 657 |
| 623 void WorkQueue::SetTaskCount(int count) { | 658 void WorkQueue::SetTaskCount(int count) { |
| 624 task_count_ = count; | 659 task_count_ = count; |
| 625 } | 660 } |
| 626 | 661 |
| 627 void WorkQueue::SetAllowHelp(bool allow) { | 662 void WorkQueue::SetAllowHelp(bool allow) { |
| 628 allow_help_requests_ = allow; | 663 allow_help_requests_ = allow; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 | 728 |
| 694 { | 729 { |
| 695 AutoLock auto_lock(lock_); | 730 AutoLock auto_lock(lock_); |
| 696 // Send notification that we completed our "work." | 731 // Send notification that we completed our "work." |
| 697 WorkIsCompleted(thread_id); | 732 WorkIsCompleted(thread_id); |
| 698 } | 733 } |
| 699 } | 734 } |
| 700 } | 735 } |
| 701 | 736 |
| 702 } // namespace | 737 } // namespace |
| OLD | NEW |