Index: base/synchronization/condition_variable_unittest.cc |
diff --git a/base/synchronization/condition_variable_unittest.cc b/base/synchronization/condition_variable_unittest.cc |
index d60b2b8af58aa55c48886933c7682fb452d9f963..28498526748ad5571fcf51ec46e6a1f5aaf1b5a5 100644 |
--- a/base/synchronization/condition_variable_unittest.cc |
+++ b/base/synchronization/condition_variable_unittest.cc |
@@ -254,148 +254,151 @@ TEST_F(ConditionVariableTest, DISABLED_TimeoutAcrossSetTimeOfDay) { |
#define MAYBE_MultiThreadConsumerTest MultiThreadConsumerTest |
#endif |
// Test serial task servicing, as well as two parallel task servicing methods. |
-TEST_F(ConditionVariableTest, MAYBE_MultiThreadConsumerTest) { |
- const int kThreadCount = 10; |
- WorkQueue queue(kThreadCount); // Start the threads. |
- |
- const int kTaskCount = 10; // Number of tasks in each mini-test here. |
- |
- Time start_time; // Used to time task processing. |
- |
- { |
- base::AutoLock auto_lock(*queue.lock()); |
- while (!queue.EveryIdWasAllocated()) |
- queue.all_threads_have_ids()->Wait(); |
- } |
- |
- // If threads aren't in a wait state, they may start to gobble up tasks in |
- // parallel, short-circuiting (breaking) this test. |
- queue.SpinUntilAllThreadsAreWaiting(); |
- |
- { |
- // Since we have no tasks yet, all threads should be waiting by now. |
- base::AutoLock auto_lock(*queue.lock()); |
- EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks()); |
- EXPECT_EQ(0, queue.task_count()); |
- EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread()); |
- EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
- EXPECT_EQ(0, queue.GetNumberOfCompletedTasks()); |
+TEST_F(ConditionVariableTest, MultiThreadConsumerTest) { |
+ int current_test = 0; |
+ while (++current_test <= 5000) { |
+ const int kThreadCount = 10; |
+ WorkQueue queue(kThreadCount); // Start the threads. |
- // Set up to make each task include getting help from another worker, so |
- // so that the work gets done in paralell. |
- queue.ResetHistory(); |
- queue.SetTaskCount(kTaskCount); |
- queue.SetWorkTime(kThirtyMs); |
- queue.SetAllowHelp(true); |
+ const int kTaskCount = 10; // Number of tasks in each mini-test here. |
- start_time = Time::Now(); |
- } |
+ Time start_time; // Used to time task processing. |
- queue.work_is_available()->Signal(); // But each worker can signal another. |
- // Wait till we at least start to handle tasks (and we're not all waiting). |
- queue.SpinUntilTaskCountLessThan(kTaskCount); |
- // Wait to allow the all workers to get done. |
- queue.SpinUntilAllThreadsAreWaiting(); |
+ { |
+ base::AutoLock auto_lock(*queue.lock()); |
+ while (!queue.EveryIdWasAllocated()) |
+ queue.all_threads_have_ids()->Wait(); |
+ } |
- { |
- // Wait until all work tasks have at least been assigned. |
- base::AutoLock auto_lock(*queue.lock()); |
- while (queue.task_count()) |
- queue.no_more_tasks()->Wait(); |
+ // If threads aren't in a wait state, they may start to gobble up tasks in |
+ // parallel, short-circuiting (breaking) this test. |
+ queue.SpinUntilAllThreadsAreWaiting(); |
- // To avoid racy assumptions, we'll just assert that at least 2 threads |
- // did work. We know that the first worker should have gone to sleep, and |
- // hence a second worker should have gotten an assignment. |
- EXPECT_LE(2, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(kTaskCount, queue.GetNumberOfCompletedTasks()); |
+ { |
+ // Since we have no tasks yet, all threads should be waiting by now. |
+ base::AutoLock auto_lock(*queue.lock()); |
+ EXPECT_EQ(0, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(0, queue.GetNumThreadsCompletingTasks()); |
+ EXPECT_EQ(0, queue.task_count()); |
+ EXPECT_EQ(0, queue.GetMaxCompletionsByWorkerThread()); |
+ EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
+ EXPECT_EQ(0, queue.GetNumberOfCompletedTasks()); |
+ |
+ // Set up to make each task include getting help from another worker, so |
+ // so that the work gets done in paralell. |
+ queue.ResetHistory(); |
+ queue.SetTaskCount(kTaskCount); |
+ queue.SetWorkTime(kThirtyMs); |
+ queue.SetAllowHelp(true); |
+ |
+ start_time = Time::Now(); |
+ } |
- // Try to ask all workers to help, and only a few will do the work. |
- queue.ResetHistory(); |
- queue.SetTaskCount(3); |
- queue.SetWorkTime(kThirtyMs); |
- queue.SetAllowHelp(false); |
- } |
- queue.work_is_available()->Broadcast(); // Make them all try. |
- // Wait till we at least start to handle tasks (and we're not all waiting). |
- queue.SpinUntilTaskCountLessThan(3); |
- // Wait to allow the 3 workers to get done. |
- queue.SpinUntilAllThreadsAreWaiting(); |
+ queue.work_is_available()->Signal(); // But each worker can signal another. |
+ // Wait till we at least start to handle tasks (and we're not all waiting). |
+ queue.SpinUntilTaskCountLessThan(kTaskCount); |
+ // Wait to allow the all workers to get done. |
+ queue.SpinUntilAllThreadsAreWaiting(); |
- { |
- base::AutoLock auto_lock(*queue.lock()); |
- EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
- EXPECT_EQ(0, queue.task_count()); |
- EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
- EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
- EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
- |
- // Set up to make each task get help from another worker. |
- queue.ResetHistory(); |
- queue.SetTaskCount(3); |
- queue.SetWorkTime(kThirtyMs); |
- queue.SetAllowHelp(true); // Allow (unnecessary) help requests. |
- } |
- queue.work_is_available()->Broadcast(); // Signal all threads. |
- // Wait till we at least start to handle tasks (and we're not all waiting). |
- queue.SpinUntilTaskCountLessThan(3); |
- // Wait to allow the 3 workers to get done. |
- queue.SpinUntilAllThreadsAreWaiting(); |
+ { |
+ // Wait until all work tasks have at least been assigned. |
+ base::AutoLock auto_lock(*queue.lock()); |
+ while (queue.task_count()) |
+ queue.no_more_tasks()->Wait(); |
+ |
+ // To avoid racy assumptions, we'll just assert that at least 2 threads |
+ // did work. We know that the first worker should have gone to sleep, and |
+ // hence a second worker should have gotten an assignment. |
+ EXPECT_LE(2, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(kTaskCount, queue.GetNumberOfCompletedTasks()); |
+ |
+ // Try to ask all workers to help, and only a few will do the work. |
+ queue.ResetHistory(); |
+ queue.SetTaskCount(3); |
+ queue.SetWorkTime(kThirtyMs); |
+ queue.SetAllowHelp(false); |
+ } |
+ queue.work_is_available()->Broadcast(); // Make them all try. |
+ // Wait till we at least start to handle tasks (and we're not all waiting). |
+ queue.SpinUntilTaskCountLessThan(3); |
+ // Wait to allow the 3 workers to get done. |
+ queue.SpinUntilAllThreadsAreWaiting(); |
- { |
- base::AutoLock auto_lock(*queue.lock()); |
- EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
- EXPECT_EQ(0, queue.task_count()); |
- EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
- EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
- EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
+ { |
+ base::AutoLock auto_lock(*queue.lock()); |
+ EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
+ EXPECT_EQ(0, queue.task_count()); |
+ EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
+ EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
+ EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
+ |
+ // Set up to make each task get help from another worker. |
+ queue.ResetHistory(); |
+ queue.SetTaskCount(3); |
+ queue.SetWorkTime(kThirtyMs); |
+ queue.SetAllowHelp(true); // Allow (unnecessary) help requests. |
+ } |
+ queue.work_is_available()->Broadcast(); // Signal all threads. |
+ // Wait till we at least start to handle tasks (and we're not all waiting). |
+ queue.SpinUntilTaskCountLessThan(3); |
+ // Wait to allow the 3 workers to get done. |
+ queue.SpinUntilAllThreadsAreWaiting(); |
- // Set up to make each task get help from another worker. |
- queue.ResetHistory(); |
- queue.SetTaskCount(20); // 2 tasks per thread. |
- queue.SetWorkTime(kThirtyMs); |
- queue.SetAllowHelp(true); |
- } |
- queue.work_is_available()->Signal(); // But each worker can signal another. |
- // Wait till we at least start to handle tasks (and we're not all waiting). |
- queue.SpinUntilTaskCountLessThan(20); |
- // Wait to allow the 10 workers to get done. |
- queue.SpinUntilAllThreadsAreWaiting(); // Should take about 60 ms. |
+ { |
+ base::AutoLock auto_lock(*queue.lock()); |
+ EXPECT_EQ(3, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(3, queue.GetNumThreadsCompletingTasks()); |
+ EXPECT_EQ(0, queue.task_count()); |
+ EXPECT_EQ(1, queue.GetMaxCompletionsByWorkerThread()); |
+ EXPECT_EQ(0, queue.GetMinCompletionsByWorkerThread()); |
+ EXPECT_EQ(3, queue.GetNumberOfCompletedTasks()); |
+ |
+ // Set up to make each task get help from another worker. |
+ queue.ResetHistory(); |
+ queue.SetTaskCount(20); // 2 tasks per thread. |
+ queue.SetWorkTime(kThirtyMs); |
+ queue.SetAllowHelp(true); |
+ } |
+ queue.work_is_available()->Signal(); // But each worker can signal another. |
+ // Wait till we at least start to handle tasks (and we're not all waiting). |
+ queue.SpinUntilTaskCountLessThan(20); |
+ // Wait to allow the 10 workers to get done. |
+ queue.SpinUntilAllThreadsAreWaiting(); // Should take about 60 ms. |
- { |
- base::AutoLock auto_lock(*queue.lock()); |
- EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
- EXPECT_EQ(0, queue.task_count()); |
- EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
+ { |
+ base::AutoLock auto_lock(*queue.lock()); |
+ EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
+ EXPECT_EQ(0, queue.task_count()); |
+ EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
+ |
+ // Same as last test, but with Broadcast(). |
+ queue.ResetHistory(); |
+ queue.SetTaskCount(20); // 2 tasks per thread. |
+ queue.SetWorkTime(kThirtyMs); |
+ queue.SetAllowHelp(true); |
+ } |
+ queue.work_is_available()->Broadcast(); |
+ // Wait till we at least start to handle tasks (and we're not all waiting). |
+ queue.SpinUntilTaskCountLessThan(20); |
+ // Wait to allow the 10 workers to get done. |
+ queue.SpinUntilAllThreadsAreWaiting(); // Should take about 60 ms. |
- // Same as last test, but with Broadcast(). |
- queue.ResetHistory(); |
- queue.SetTaskCount(20); // 2 tasks per thread. |
- queue.SetWorkTime(kThirtyMs); |
- queue.SetAllowHelp(true); |
- } |
- queue.work_is_available()->Broadcast(); |
- // Wait till we at least start to handle tasks (and we're not all waiting). |
- queue.SpinUntilTaskCountLessThan(20); |
- // Wait to allow the 10 workers to get done. |
- queue.SpinUntilAllThreadsAreWaiting(); // Should take about 60 ms. |
+ { |
+ base::AutoLock auto_lock(*queue.lock()); |
+ EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
+ EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
+ EXPECT_EQ(0, queue.task_count()); |
+ EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
- { |
- base::AutoLock auto_lock(*queue.lock()); |
- EXPECT_EQ(10, queue.GetNumThreadsTakingAssignments()); |
- EXPECT_EQ(10, queue.GetNumThreadsCompletingTasks()); |
- EXPECT_EQ(0, queue.task_count()); |
- EXPECT_EQ(20, queue.GetNumberOfCompletedTasks()); |
+ queue.SetShutdown(); |
+ } |
+ queue.work_is_available()->Broadcast(); // Force check for shutdown. |
- queue.SetShutdown(); |
+ SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE( |
+ TimeDelta::FromMinutes(1), queue.ThreadSafeCheckShutdown(kThreadCount)); |
} |
- queue.work_is_available()->Broadcast(); // Force check for shutdown. |
- |
- SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1), |
- queue.ThreadSafeCheckShutdown(kThreadCount)); |
} |
TEST_F(ConditionVariableTest, LargeFastTaskTest) { |