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

Unified Diff: base/synchronization/condition_variable_unittest.cc

Issue 2388083002: Test MultiThreadConsumerTest.
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/synchronization/condition_variable_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..5656a73c93675d038c6d54ab926935f57d12e4cc 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 <= 100) {
+ 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) {
« no previous file with comments | « no previous file | base/synchronization/condition_variable_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698