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

Unified Diff: base/task_scheduler/task_tracker_unittest.cc

Issue 2019763002: TaskScheduler: Atomic operations in TaskTracker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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
« base/task_scheduler/task_tracker.cc ('K') | « base/task_scheduler/task_tracker.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/task_scheduler/task_tracker_unittest.cc
diff --git a/base/task_scheduler/task_tracker_unittest.cc b/base/task_scheduler/task_tracker_unittest.cc
index 8f04f3a02e35636e2c2a018ba93cfb2bc4a7bd98..dcd8fea02c9e139fec394b4f661730898628f437 100644
--- a/base/task_scheduler/task_tracker_unittest.cc
+++ b/base/task_scheduler/task_tracker_unittest.cc
@@ -5,6 +5,7 @@
#include "base/task_scheduler/task_tracker.h"
#include <memory>
+#include <vector>
#include "base/bind.h"
#include "base/logging.h"
@@ -14,6 +15,7 @@
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task_scheduler/scheduler_lock.h"
#include "base/task_scheduler/task.h"
#include "base/task_scheduler/task_traits.h"
#include "base/task_scheduler/test_utils.h"
@@ -30,6 +32,8 @@ namespace internal {
namespace {
+constexpr size_t kLoadTestNumIterations = 100;
+
// Calls TaskTracker::Shutdown() asynchronously.
class ThreadCallingShutdown : public SimpleThread {
public:
@@ -53,19 +57,42 @@ class ThreadCallingShutdown : public SimpleThread {
DISALLOW_COPY_AND_ASSIGN(ThreadCallingShutdown);
};
-// Runs a task asynchronously.
-class ThreadRunningTask : public SimpleThread {
+class ThreadPostingAndRunningTask : public SimpleThread {
public:
- ThreadRunningTask(TaskTracker* tracker, const Task* task)
- : SimpleThread("ThreadRunningTask"), tracker_(tracker), task_(task) {}
+ enum Action {
+ WILL_POST = 0x1,
+ RUN = 0x2,
+ WILL_POST_AND_RUN = WILL_POST | RUN,
+ };
+
+ ThreadPostingAndRunningTask(TaskTracker* tracker,
+ const Task* task,
+ Action action,
+ bool expect_post_succeeds)
+ : SimpleThread("ThreadPostingAndRunningTask"),
+ tracker_(tracker),
+ task_(task),
+ action_(action),
+ expect_post_succeeds_(expect_post_succeeds) {}
private:
- void Run() override { tracker_->RunTask(task_); }
+ void Run() override {
+ bool post_succeeded = true;
+ if (action_ & WILL_POST) {
+ post_succeeded = tracker_->WillPostTask(task_);
+ EXPECT_EQ(expect_post_succeeds_, post_succeeded);
+ }
+ if (post_succeeded && action_ & RUN)
+ tracker_->RunTask(task_);
+ }
TaskTracker* const tracker_;
const Task* const task_;
+ const Action action_;
+ const bool expect_post_succeeds_;
- DISALLOW_COPY_AND_ASSIGN(ThreadRunningTask);
+ DISALLOW_COPY_AND_ASSIGN(ThreadPostingAndRunningTask);
+ ;
};
class ScopedSetSingletonAllowed {
@@ -121,14 +148,26 @@ class TaskSchedulerTaskTrackerTest
EXPECT_TRUE(tracker_.IsShuttingDownForTesting());
}
+ size_t NumTasksExecuted() {
+ AutoSchedulerLock auto_lock(lock_);
+ return num_tasks_executed_;
+ }
+
TaskTracker tracker_;
- size_t num_tasks_executed_ = 0;
private:
- void RunTaskCallback() { ++num_tasks_executed_; }
+ void RunTaskCallback() {
+ AutoSchedulerLock auto_lock(lock_);
+ ++num_tasks_executed_;
+ }
std::unique_ptr<ThreadCallingShutdown> thread_calling_shutdown_;
+ // Synchronizes accesses to |num_tasks_executed_|.
+ SchedulerLock lock_;
+
+ size_t num_tasks_executed_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(TaskSchedulerTaskTrackerTest);
};
@@ -153,9 +192,9 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) {
EXPECT_TRUE(tracker_.WillPostTask(task.get()));
// Run the task.
- EXPECT_EQ(0U, num_tasks_executed_);
+ EXPECT_EQ(0U, NumTasksExecuted());
tracker_.RunTask(task.get());
- EXPECT_EQ(1U, num_tasks_executed_);
+ EXPECT_EQ(1U, NumTasksExecuted());
// Shutdown() shouldn't block.
tracker_.Shutdown();
@@ -172,7 +211,8 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) {
EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get()));
// Run the task asynchronouly.
- ThreadRunningTask thread_running_task(&tracker_, blocked_task.get());
+ ThreadPostingAndRunningTask thread_running_task(
+ &tracker_, blocked_task.get(), ThreadPostingAndRunningTask::RUN, false);
thread_running_task.Start();
// Initiate shutdown while the task is running.
@@ -212,16 +252,16 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunDuringShutdown) {
// Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it
// should be discarded.
- EXPECT_EQ(0U, num_tasks_executed_);
+ EXPECT_EQ(0U, NumTasksExecuted());
tracker_.RunTask(task.get());
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 1U : 0U,
- num_tasks_executed_);
+ NumTasksExecuted());
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
// Unblock shutdown by running the remaining BLOCK_SHUTDOWN task.
tracker_.RunTask(block_shutdown_task.get());
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U,
- num_tasks_executed_);
+ NumTasksExecuted());
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
}
@@ -232,14 +272,14 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) {
// Call Shutdown() asynchronously.
CallShutdownAsync();
- EXPECT_EQ(0U, num_tasks_executed_);
+ EXPECT_EQ(0U, NumTasksExecuted());
if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
// Run the task to unblock shutdown.
tracker_.RunTask(task.get());
- EXPECT_EQ(1U, num_tasks_executed_);
+ EXPECT_EQ(1U, NumTasksExecuted());
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
// It is not possible to test running a BLOCK_SHUTDOWN task posted before
@@ -250,7 +290,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) {
// The task shouldn't be allowed to run after shutdown.
tracker_.RunTask(task.get());
- EXPECT_EQ(0U, num_tasks_executed_);
+ EXPECT_EQ(0U, NumTasksExecuted());
}
}
@@ -271,9 +311,9 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) {
EXPECT_TRUE(tracker_.WillPostTask(task.get()));
// Run the BLOCK_SHUTDOWN task.
- EXPECT_EQ(0U, num_tasks_executed_);
+ EXPECT_EQ(0U, NumTasksExecuted());
tracker_.RunTask(task.get());
- EXPECT_EQ(1U, num_tasks_executed_);
+ EXPECT_EQ(1U, NumTasksExecuted());
} else {
// It shouldn't be allowed to post a non BLOCK_SHUTDOWN task.
std::unique_ptr<Task> task(CreateTask(GetParam()));
@@ -286,7 +326,7 @@ TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) {
VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
tracker_.RunTask(block_shutdown_task.get());
EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U,
- num_tasks_executed_);
+ NumTasksExecuted());
WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
}
@@ -420,5 +460,139 @@ INSTANTIATE_TEST_CASE_P(
TaskSchedulerTaskTrackerTest,
::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN));
+TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) {
+ // Post and run tasks asynchronously.
+ std::vector<std::unique_ptr<Task>> tasks;
+ std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
+
+ for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
+ tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, true)));
+ threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, true)));
+ threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, true)));
+ threads.back()->Start();
+ }
+
+ for (const auto& thread : threads)
+ thread->Join();
+
+ // Expect all tasks to be executed.
+ EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted());
+
+ // Should return immediately because no tasks are blocking shutdown.
+ tracker_.Shutdown();
+}
+
+TEST_F(TaskSchedulerTaskTrackerTest,
+ LoadWillPostBeforeShutdownAndRunDuringShutdown) {
+ // Post tasks asynchronously.
+ std::vector<std::unique_ptr<Task>> tasks;
+ std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads;
+
+ for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
+ tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
+ post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(), ThreadPostingAndRunningTask::WILL_POST,
+ true)));
+ post_threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
+ post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(), ThreadPostingAndRunningTask::WILL_POST,
+ true)));
+ post_threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN));
+ post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(), ThreadPostingAndRunningTask::WILL_POST,
+ true)));
+ post_threads.back()->Start();
+ }
+
+ for (const auto& thread : post_threads)
+ thread->Join();
+
+ // Call Shutdown() asynchronously.
+ CallShutdownAsync();
+
+ // Run tasks asynchronously.
+ std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads;
+
+ for (const auto& task : tasks) {
+ run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, task.get(), ThreadPostingAndRunningTask::RUN, false)));
+ run_threads.back()->Start();
+ }
+
+ for (const auto& thread : run_threads)
+ thread->Join();
+
+ WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
+
+ // Expect BLOCK_SHUTDOWN tasks to have been executed.
+ EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
+}
+
+TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) {
+ // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
+ // block shutdown.
+ std::unique_ptr<Task> block_shutdown_task(
+ CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN));
+ EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get()));
+
+ // Call Shutdown() asynchronously.
+ CallShutdownAsync();
+
+ // Post and run tasks asynchronously.
+ std::vector<std::unique_ptr<Task>> tasks;
+ std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
+
+ for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
+ tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, false)));
+ threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, false)));
+ threads.back()->Start();
+
+ tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN));
+ threads.push_back(WrapUnique(new ThreadPostingAndRunningTask(
+ &tracker_, tasks.back().get(),
+ ThreadPostingAndRunningTask::WILL_POST_AND_RUN, true)));
+ threads.back()->Start();
+ }
+
+ for (const auto& thread : threads)
+ thread->Join();
+
+ // Expect BLOCK_SHUTDOWN tasks to have been executed.
+ EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
+
+ // Shutdown() shouldn't return before |block_shutdown_task| is executed.
+ VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
+
+ // Unblock shutdown by running |block_shutdown_task|.
+ tracker_.RunTask(block_shutdown_task.get());
+ EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted());
+ WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
+}
+
} // namespace internal
} // namespace base
« base/task_scheduler/task_tracker.cc ('K') | « base/task_scheduler/task_tracker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698