Commit b7aa302b authored by Farah Charab's avatar Farah Charab Committed by Commit Bot

SQM Fuzzer: Follow-up patch for cl 1165145.

Follow up patch for comment on line 215 in sequence_manager_processor.h
for https://chromium-review.googlesource.com/c/chromium/src/+/1165145/4.

We move some interfaces from SequenceManagerFuzzerProcessor to
ThreadData to hide member variables of ThreadData.

Change-Id: I4793fe7d7514a4730d1bfc08deba8b92b68667a1
Reviewed-on: https://chromium-review.googlesource.com/1176087
Commit-Queue: Farah Charab <farahcharab@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584489}
parent a54cd17b
...@@ -242,15 +242,15 @@ source_set("scheduler_fuzzer_tests") { ...@@ -242,15 +242,15 @@ source_set("scheduler_fuzzer_tests") {
if (is_linux) { if (is_linux) {
sources += [ sources += [
"base/sequence_manager_fuzzer_processor.cc", "test/fuzzer/sequence_manager_fuzzer_processor.cc",
"base/sequence_manager_fuzzer_processor.h", "test/fuzzer/sequence_manager_fuzzer_processor.h",
"base/sequence_manager_fuzzer_processor_unittest.cc", "test/fuzzer/sequence_manager_fuzzer_processor_unittest.cc",
"base/simple_thread_impl.cc", "test/fuzzer/simple_thread_impl.cc",
"base/simple_thread_impl.h", "test/fuzzer/simple_thread_impl.h",
"base/thread_data.cc", "test/fuzzer/thread_manager.cc",
"base/thread_data.h", "test/fuzzer/thread_manager.h",
"base/thread_pool_manager.cc", "test/fuzzer/thread_pool_manager.cc",
"base/thread_pool_manager.h", "test/fuzzer/thread_pool_manager.h",
] ]
deps += [ deps += [
...@@ -264,15 +264,15 @@ source_set("scheduler_fuzzer_tests") { ...@@ -264,15 +264,15 @@ source_set("scheduler_fuzzer_tests") {
fuzzer_test("sequence_manager_fuzzer") { fuzzer_test("sequence_manager_fuzzer") {
sources = [ sources = [
"base/sequence_manager_fuzzer.cc", "test/fuzzer/sequence_manager_fuzzer.cc",
"base/sequence_manager_fuzzer_processor.cc", "test/fuzzer/sequence_manager_fuzzer_processor.cc",
"base/sequence_manager_fuzzer_processor.h", "test/fuzzer/sequence_manager_fuzzer_processor.h",
"base/simple_thread_impl.cc", "test/fuzzer/simple_thread_impl.cc",
"base/simple_thread_impl.h", "test/fuzzer/simple_thread_impl.h",
"base/thread_data.cc", "test/fuzzer/thread_manager.cc",
"base/thread_data.h", "test/fuzzer/thread_manager.h",
"base/thread_pool_manager.cc", "test/fuzzer/thread_pool_manager.cc",
"base/thread_pool_manager.h", "test/fuzzer/thread_pool_manager.h",
] ]
deps = [ deps = [
...@@ -285,6 +285,6 @@ fuzzer_test("sequence_manager_fuzzer") { ...@@ -285,6 +285,6 @@ fuzzer_test("sequence_manager_fuzzer") {
proto_library("sequence_manager_test_description_proto") { proto_library("sequence_manager_test_description_proto") {
sources = [ sources = [
"base/proto/sequence_manager_test_description.proto", "test/fuzzer/proto/sequence_manager_test_description.proto",
] ]
} }
...@@ -6,10 +6,3 @@ include_rules = [ ...@@ -6,10 +6,3 @@ include_rules = [
"+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/platform_export.h",
"+base", "+base",
] ]
specific_include_rules = {
"sequence_manager_fuzzer_processor_unittest.cc": [
"+third_party/protobuf/src/google/protobuf/text_format.h",
"+third_party/protobuf/src/google/protobuf/util/message_differencer.h",
],
}
#include "third_party/blink/renderer/platform/scheduler/base/simple_thread_impl.h"
namespace base {
namespace sequence_manager {
SimpleThreadImpl::SimpleThreadImpl(ThreadCallback callback,
TimeTicks initial_time)
: SimpleThread("TestThread"),
callback_(std::move(callback)),
initial_time_(initial_time) {}
void SimpleThreadImpl::Run() {
std::unique_ptr<ThreadData> thread_data =
std::make_unique<ThreadData>(initial_time_);
thread_data_ = thread_data.get();
std::move(callback_).Run(thread_data_);
thread_can_shutdown_.Wait();
}
SimpleThreadImpl::~SimpleThreadImpl() {
thread_can_shutdown_.Signal();
Join();
}
ThreadData* SimpleThreadImpl::thread_data() const {
return thread_data_;
}
} // namespace sequence_manager
} // namespace base
#include "third_party/blink/renderer/platform/scheduler/base/thread_data.h"
#include "base/task/sequence_manager/test/test_task_queue.h"
#include "base/threading/thread_task_runner_handle.h"
namespace base {
namespace sequence_manager {
ThreadData::ThreadData(TimeTicks initial_time) {
test_task_runner_ = WrapRefCounted(
new TestMockTimeTaskRunner(TestMockTimeTaskRunner::Type::kBoundToThread));
DCHECK(!(initial_time - TimeTicks()).is_zero())
<< "A zero clock is not allowed as empty TimeTicks have a special value "
"(i.e. base::TimeTicks::is_null())";
test_task_runner_->AdvanceMockTickClock(initial_time - TimeTicks());
manager_ =
SequenceManagerForTest::Create(nullptr, ThreadTaskRunnerHandle::Get(),
test_task_runner_->GetMockTickClock());
TaskQueue::Spec spec = TaskQueue::Spec("default_task_queue");
task_queues_.emplace_back(manager_->CreateTaskQueue<TestTaskQueue>(spec));
}
ThreadData::~ThreadData() = default;
} // namespace sequence_manager
} // namespace base
...@@ -152,7 +152,7 @@ message SequenceManagerTestDescription { ...@@ -152,7 +152,7 @@ message SequenceManagerTestDescription {
repeated Action initial_thread_actions = 1; repeated Action initial_thread_actions = 1;
} }
message InitialThread { message CreateInitialThreadAction {
// NEXT ID = 3 // NEXT ID = 3
optional uint64 action_id = 1; optional uint64 action_id = 1;
...@@ -160,5 +160,5 @@ message SequenceManagerTestDescription { ...@@ -160,5 +160,5 @@ message SequenceManagerTestDescription {
required CreateThreadAction create_thread = 2; required CreateThreadAction create_thread = 2;
} }
repeated InitialThread main_thread_actions = 1; repeated CreateInitialThreadAction main_thread_actions = 1;
} }
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
#include <iostream> #include <iostream>
#include "testing/libfuzzer/proto/lpm_interface.h" #include "testing/libfuzzer/proto/lpm_interface.h"
#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/proto/sequence_manager_test_description.pb.h"
#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h"
// Tests some APIs in base::sequence_manager::SequenceManager (ones defined in // Tests some APIs in base::sequence_manager::SequenceManager (ones defined in
// SequenceManagerTesrDescription proto) for crashes, hangs, memory leaks, // SequenceManagerTesrDescription proto) for crashes, hangs, memory leaks,
......
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h"
namespace base {
namespace sequence_manager {
void SequenceManagerFuzzerProcessor::ParseAndRun(
const SequenceManagerTestDescription& description) {
SequenceManagerFuzzerProcessor processor;
processor.RunTest(description);
}
SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor()
: SequenceManagerFuzzerProcessor(false) {}
SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor(
bool log_for_testing)
: log_for_testing_(log_for_testing),
initial_time_(TimeTicks() + TimeDelta::FromMilliseconds(1)),
thread_pool_manager_(std::make_unique<ThreadPoolManager>(this)),
main_thread_manager_(
std::make_unique<ThreadManager>(initial_time_, this)) {}
SequenceManagerFuzzerProcessor::~SequenceManagerFuzzerProcessor() = default;
void SequenceManagerFuzzerProcessor::RunTest(
const SequenceManagerTestDescription& description) {
for (const auto& initial_action : description.main_thread_actions()) {
main_thread_manager_->ExecuteCreateThreadAction(
initial_action.action_id(), initial_action.create_thread());
}
thread_pool_manager_->StartInitialThreads();
thread_pool_manager_->WaitForAllThreads();
if (log_for_testing_) {
ordered_actions_.emplace_back(main_thread_manager_->ordered_actions());
ordered_tasks_.emplace_back(main_thread_manager_->ordered_tasks());
for (auto&& thread : (thread_pool_manager_->threads())) {
DCHECK(thread->thread_manager());
ordered_actions_.emplace_back(
thread->thread_manager()->ordered_actions());
ordered_tasks_.emplace_back(thread->thread_manager()->ordered_tasks());
}
}
}
void SequenceManagerFuzzerProcessor::LogTaskForTesting(
std::vector<TaskForTest>* ordered_tasks,
uint64_t task_id,
TimeTicks start_time,
TimeTicks end_time) {
if (!log_for_testing_)
return;
uint64_t start_time_ms = (start_time - initial_time_).InMilliseconds();
uint64_t end_time_ms = (end_time - initial_time_).InMilliseconds();
ordered_tasks->emplace_back(task_id, start_time_ms, end_time_ms);
}
void SequenceManagerFuzzerProcessor::LogActionForTesting(
std::vector<ActionForTest>* ordered_actions,
uint64_t action_id,
ActionForTest::ActionType type,
TimeTicks start_time) {
if (!log_for_testing_)
return;
ordered_actions->emplace_back(action_id, type,
(start_time - initial_time_).InMilliseconds());
}
const std::vector<std::vector<SequenceManagerFuzzerProcessor::TaskForTest>>&
SequenceManagerFuzzerProcessor::ordered_tasks() const {
return ordered_tasks_;
}
const std::vector<std::vector<SequenceManagerFuzzerProcessor::ActionForTest>>&
SequenceManagerFuzzerProcessor::ordered_actions() const {
return ordered_actions_;
}
SequenceManagerFuzzerProcessor::TaskForTest::TaskForTest(uint64_t id,
uint64_t start_time_ms,
uint64_t end_time_ms)
: task_id(id), start_time_ms(start_time_ms), end_time_ms(end_time_ms) {}
bool SequenceManagerFuzzerProcessor::TaskForTest::operator==(
const TaskForTest& rhs) const {
return task_id == rhs.task_id && start_time_ms == rhs.start_time_ms &&
end_time_ms == rhs.end_time_ms;
}
SequenceManagerFuzzerProcessor::ActionForTest::ActionForTest(
uint64_t id,
ActionType type,
uint64_t start_time_ms)
: action_id(id), action_type(type), start_time_ms(start_time_ms) {}
bool SequenceManagerFuzzerProcessor::ActionForTest::operator==(
const ActionForTest& rhs) const {
return action_id == rhs.action_id && action_type == rhs.action_type &&
start_time_ms == rhs.start_time_ms;
}
ThreadPoolManager* SequenceManagerFuzzerProcessor::thread_pool_manager() const {
return thread_pool_manager_.get();
}
} // namespace sequence_manager
} // namespace base
...@@ -2,28 +2,27 @@ ...@@ -2,28 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file // found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_
#include <memory>
#include <vector> #include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/proto/sequence_manager_test_description.pb.h"
namespace base { namespace base {
namespace sequence_manager { namespace sequence_manager {
class ThreadData; class ThreadManager;
class ThreadPoolManager; class ThreadPoolManager;
// Provides functionality to parse the fuzzer's test description and run the // Provides functionality to parse the fuzzer's test description and run the
// relevant APIs. // relevant APIs.
// //
// Warning: For unit testing purposes, the thread data of the threads managed by // Warning: For unit testing purposes, the thread manager of the threads managed
// the |thread_pool_manager_| should live for the scope of the main thread // by the |thread_pool_manager_| should live for the scope of the main thread
// entry function i.e RunTest. // entry function i.e RunTest.
class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
public: public:
...@@ -31,6 +30,8 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { ...@@ -31,6 +30,8 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
// run the relevant APIs. // run the relevant APIs.
static void ParseAndRun(const SequenceManagerTestDescription& description); static void ParseAndRun(const SequenceManagerTestDescription& description);
ThreadPoolManager* thread_pool_manager() const;
protected: protected:
struct TaskForTest { struct TaskForTest {
TaskForTest(uint64_t id, uint64_t start_time_ms, uint64_t end_time_ms); TaskForTest(uint64_t id, uint64_t start_time_ms, uint64_t end_time_ms);
...@@ -64,19 +65,6 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { ...@@ -64,19 +65,6 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
uint64_t start_time_ms; uint64_t start_time_ms;
}; };
class Task {
public:
Task(ThreadData* thread_data, SequenceManagerFuzzerProcessor* processor);
~Task() = default;
void Execute(const SequenceManagerTestDescription::Task& task);
bool is_running;
SequenceManagerFuzzerProcessor* processor_;
ThreadData* thread_data_;
base::WeakPtrFactory<Task> weak_ptr_factory_;
};
SequenceManagerFuzzerProcessor(); SequenceManagerFuzzerProcessor();
explicit SequenceManagerFuzzerProcessor(bool log_for_testing); explicit SequenceManagerFuzzerProcessor(bool log_for_testing);
...@@ -85,11 +73,6 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { ...@@ -85,11 +73,6 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
void RunTest(const SequenceManagerTestDescription& description); void RunTest(const SequenceManagerTestDescription& description);
void ExecuteThread(
ThreadData* thread_data,
const google::protobuf::RepeatedPtrField<
SequenceManagerTestDescription::Action>& initial_thread_actions);
// Returns an ordered list of tasks executed on each thread. Note that the // Returns an ordered list of tasks executed on each thread. Note that the
// ordering of the threads isn't deterministic since it follows the order in // ordering of the threads isn't deterministic since it follows the order in
// which the threads were constructed. Furthermore, given that // which the threads were constructed. Furthermore, given that
...@@ -104,78 +87,32 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { ...@@ -104,78 +87,32 @@ class PLATFORM_EXPORT SequenceManagerFuzzerProcessor {
const std::vector<std::vector<ActionForTest>>& ordered_actions() const; const std::vector<std::vector<ActionForTest>>& ordered_actions() const;
private: private:
friend class ThreadData; friend class ThreadManager;
friend class ThreadPoolManager;
void RunAction(ThreadData* thread_data,
const SequenceManagerTestDescription::Action& action);
void ExecuteCreateThreadAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::CreateThreadAction& action);
void ExecuteCreateTaskQueueAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::CreateTaskQueueAction& action);
void ExecutePostDelayedTaskAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::PostDelayedTaskAction& action);
void ExecuteSetQueuePriorityAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::SetQueuePriorityAction& action);
void ExecuteSetQueueEnabledAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::SetQueueEnabledAction& action);
void ExecuteCreateQueueVoterAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::CreateQueueVoterAction& action);
void ExecuteShutdownTaskQueueAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::ShutdownTaskQueueAction& action);
void ExecuteCancelTaskAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::CancelTaskAction& action);
void ExecuteInsertFenceAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::InsertFenceAction& action);
void ExecuteRemoveFenceAction(
ThreadData* thread_data,
uint64_t action_id,
const SequenceManagerTestDescription::RemoveFenceAction& action);
void ExecuteTask(ThreadData* thread_data,
const SequenceManagerTestDescription::Task& task);
void DeleteTask(Task* task);
void LogTaskForTesting(ThreadData* thread_data, // Logs the task defined by the parameters passed to |ordered_tasks| if
// |log_for_testing_| is enabled.
void LogTaskForTesting(std::vector<TaskForTest>* ordered_tasks,
uint64_t task_id, uint64_t task_id,
TimeTicks start_time, TimeTicks start_time,
TimeTicks end_time); TimeTicks end_time);
void LogActionForTesting(ThreadData* thread_data, // Logs the action defined by the parameters passed to |ordered_actions| if
// |log_for_testing_| is enabled.
void LogActionForTesting(std::vector<ActionForTest>* ordered_actions,
uint64_t action_id, uint64_t action_id,
ActionForTest::ActionType type, ActionForTest::ActionType type,
TimeTicks start_time); TimeTicks start_time);
const bool log_for_testing_; const bool log_for_testing_;
TimeTicks initial_time_; const TimeTicks initial_time_;
std::unique_ptr<ThreadPoolManager> thread_pool_manager_; const std::unique_ptr<ThreadPoolManager> thread_pool_manager_;
// The clock of the main thread data task runner is initialized to // The clock of the main thread manager task runner is initialized to
// |initial_time_| and never advanced, since it can only execute actions at // |initial_time_| and never advanced, since it can only execute actions at
// the start of the program. // the start of the program.
std::unique_ptr<ThreadData> main_thread_data_; const std::unique_ptr<ThreadManager> main_thread_manager_;
// For Testing. Each entry contains the ordered list of tasks for one of the // For Testing. Each entry contains the ordered list of tasks for one of the
// created threads. The first entry is reserved for the main thread (which is // created threads. The first entry is reserved for the main thread (which is
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h"
#include <memory> #include <memory>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/proto/sequence_manager_test_description.pb.h"
#include "third_party/protobuf/src/google/protobuf/text_format.h" #include "third_party/protobuf/src/google/protobuf/text_format.h"
#include "third_party/protobuf/src/google/protobuf/util/message_differencer.h" #include "third_party/protobuf/src/google/protobuf/util/message_differencer.h"
...@@ -149,7 +149,7 @@ TEST(SequenceManagerFuzzerProcessorTest, CreateQueueVoter) { ...@@ -149,7 +149,7 @@ TEST(SequenceManagerFuzzerProcessorTest, CreateQueueVoter) {
EXPECT_THAT(executed_actions, ContainerEq(expected_actions)); EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
} }
TEST(SequenceManagerFuzzerProcessorTest, PostDelayedTaskWithDuration) { TEST(SequenceManagerFuzzerProcessorTest, PostDelayedTaskWDuration) {
std::vector<TaskForTest> executed_tasks; std::vector<TaskForTest> executed_tasks;
std::vector<ActionForTest> executed_actions; std::vector<ActionForTest> executed_actions;
...@@ -278,12 +278,12 @@ TEST(SequenceManagerFuzzerProcessorTest, SetQueueEnabled) { ...@@ -278,12 +278,12 @@ TEST(SequenceManagerFuzzerProcessorTest, SetQueueEnabled) {
EXPECT_THAT(executed_actions, ContainerEq(expected_actions)); EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
// All the tasks posted to the task queue with id 1 do not get executed since // All the tasks posted to the task queue w id 1 do not get executed since
// this task queue is disabled. // this task queue is disabled.
EXPECT_THAT(executed_tasks, IsEmpty()); EXPECT_THAT(executed_tasks, IsEmpty());
} }
TEST(SequenceManagerFuzzerProcessorTest, SetQueueEnabledWithDelays) { TEST(SequenceManagerFuzzerProcessorTest, SetQueueEnabledWDelays) {
std::vector<TaskForTest> executed_tasks; std::vector<TaskForTest> executed_tasks;
// Describes a test that posts two tasks to disable and enable a queue after // Describes a test that posts two tasks to disable and enable a queue after
...@@ -522,7 +522,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ShutdownTaskQueue) { ...@@ -522,7 +522,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ShutdownTaskQueue) {
std::vector<TaskForTest> expected_tasks; std::vector<TaskForTest> expected_tasks;
// Note that the task with id 4 isn't posted to the queue that was shutdown, // Note that the task w id 4 isn't posted to the queue that was shutdown,
// since that was posted to the first available queue (Check // since that was posted to the first available queue (Check
// sequence_manager_test_description.proto for more details). // sequence_manager_test_description.proto for more details).
expected_tasks.emplace_back(4, 0, 0); expected_tasks.emplace_back(4, 0, 0);
...@@ -755,7 +755,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ...@@ -755,7 +755,7 @@ TEST(SequenceManagerFuzzerProcessorTest,
std::vector<TaskForTest> expected_tasks; std::vector<TaskForTest> expected_tasks;
// Task with id 2 is expected to run first and block the other task until it // Task w id 2 is expected to run first and block the other task until it
// done. // done.
expected_tasks.emplace_back(2, 0, 40); expected_tasks.emplace_back(2, 0, 40);
expected_tasks.emplace_back(1, 40, 60); expected_tasks.emplace_back(1, 40, 60);
...@@ -770,7 +770,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ...@@ -770,7 +770,7 @@ TEST(SequenceManagerFuzzerProcessorTest,
} }
TEST(SequenceManagerFuzzerProcessorTest, TEST(SequenceManagerFuzzerProcessorTest,
TaskDurationBlocksOtherNonNestableTaskWhenPostedFromTheWithinTask) { TaskDurationBlocksOtherNonNestableTaskWhenPostedFromTheWinTask) {
std::vector<TaskForTest> executed_tasks; std::vector<TaskForTest> executed_tasks;
// Posts an instant task of duration 40 ms that posts another non-nested // Posts an instant task of duration 40 ms that posts another non-nested
...@@ -796,9 +796,9 @@ TEST(SequenceManagerFuzzerProcessorTest, ...@@ -796,9 +796,9 @@ TEST(SequenceManagerFuzzerProcessorTest,
std::vector<TaskForTest> expected_tasks; std::vector<TaskForTest> expected_tasks;
// Task with task id 1 is expected to run for 40 ms, and block the other // Task w task id 1 is expected to run for 40 ms, and block the other
// posted task from running until its done. Note that the task with id 2 is // posted task from running until its done. Note that the task w id 2 is
// blocked since it is non-nested, so it is not supposed to run from within // blocked since it is non-nested, so it is not supposed to run from win
// the posting task. // the posting task.
expected_tasks.emplace_back(1, 0, 40); expected_tasks.emplace_back(1, 0, 40);
expected_tasks.emplace_back(2, 40, 40); expected_tasks.emplace_back(2, 40, 40);
...@@ -865,9 +865,9 @@ TEST(SequenceManagerFuzzerProcessorTest, PostNonEmptyTask) { ...@@ -865,9 +865,9 @@ TEST(SequenceManagerFuzzerProcessorTest, PostNonEmptyTask) {
std::vector<TaskForTest> expected_tasks; std::vector<TaskForTest> expected_tasks;
// Task with task id 1 is expected to run first, and block all other pending // Task w task id 1 is expected to run first, and block all other pending
// tasks until its done. The remaining tasks will be executed in // tasks until its done. The remaining tasks will be executed in
// non-decreasing order of the delay parameter with ties broken by // non-decreasing order of the delay parameter w ties broken by
// the post order. // the post order.
expected_tasks.emplace_back(1, 5, 45); expected_tasks.emplace_back(1, 5, 45);
expected_tasks.emplace_back(3, 45, 45); expected_tasks.emplace_back(3, 45, 45);
...@@ -950,8 +950,8 @@ TEST(SequenceManagerFuzzerProcessorTest, OrderOfSimpleUnnestedExecutedActions) { ...@@ -950,8 +950,8 @@ TEST(SequenceManagerFuzzerProcessorTest, OrderOfSimpleUnnestedExecutedActions) {
std::vector<TaskForTest> expected_tasks; std::vector<TaskForTest> expected_tasks;
// Tasks are expected to run in order of non-decreasing delay with ties broken // Tasks are expected to run in order of non-decreasing delay w ties broken
// by order of posting. Note that the task with id 3 will block the task with // by order of posting. Note that the task w id 3 will block the task with
// id 2 from running at its scheduled time. // id 2 from running at its scheduled time.
expected_tasks.emplace_back(1, 10, 10); expected_tasks.emplace_back(1, 10, 10);
expected_tasks.emplace_back(3, 15, 25); expected_tasks.emplace_back(3, 15, 25);
...@@ -1052,7 +1052,7 @@ TEST(SequenceManagerFuzzerProcessorTest, InsertAndRemoveFence) { ...@@ -1052,7 +1052,7 @@ TEST(SequenceManagerFuzzerProcessorTest, InsertAndRemoveFence) {
expected_tasks.emplace_back(1, 20, 20); expected_tasks.emplace_back(1, 20, 20);
expected_tasks.emplace_back(2, 30, 30); expected_tasks.emplace_back(2, 30, 30);
// Task with id 3 will not execute until the fence is removed from the task // Task w id 3 will not execute until the fence is removed from the task
// queue it was posted to. // queue it was posted to.
expected_tasks.emplace_back(3, 30, 30); expected_tasks.emplace_back(3, 30, 30);
...@@ -1091,7 +1091,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ThrottleTaskQueue) { ...@@ -1091,7 +1091,7 @@ TEST(SequenceManagerFuzzerProcessorTest, ThrottleTaskQueue) {
EXPECT_THAT(executed_actions, ContainerEq(expected_actions)); EXPECT_THAT(executed_actions, ContainerEq(expected_actions));
// Task queue with id 1 is throttled, so posted tasks will not get executed. // Task queue w id 1 is throttled, so posted tasks will not get executed.
EXPECT_THAT(executed_tasks, IsEmpty()); EXPECT_THAT(executed_tasks, IsEmpty());
} }
...@@ -1151,7 +1151,7 @@ TEST(SequenceManagerFuzzerProcessorTest, MultipleThreadsButNotInteracting) { ...@@ -1151,7 +1151,7 @@ TEST(SequenceManagerFuzzerProcessorTest, MultipleThreadsButNotInteracting) {
} }
})"; })";
// Threads initialized with same list of actions. // Threads initialized w same list of actions.
std::vector<std::string> threads{thread_actions, thread_actions, std::vector<std::string> threads{thread_actions, thread_actions,
thread_actions, thread_actions, thread_actions, thread_actions,
thread_actions}; thread_actions};
...@@ -1168,8 +1168,8 @@ TEST(SequenceManagerFuzzerProcessorTest, MultipleThreadsButNotInteracting) { ...@@ -1168,8 +1168,8 @@ TEST(SequenceManagerFuzzerProcessorTest, MultipleThreadsButNotInteracting) {
for (int i = 1; i <= 5; i++) { for (int i = 1; i <= 5; i++) {
// Created thread tasks: tasks are expected to run in order of // Created thread tasks: tasks are expected to run in order of
// non-decreasing delay with ties broken by order of posting. Note that the // non-decreasing delay w ties broken by order of posting. Note that the
// task with id 3 will block the task with id 2 from running at its // task w id 3 will block the task with id 2 from running at its
// scheduled time. // scheduled time.
expected_tasks[i].emplace_back(1, 10, 10); expected_tasks[i].emplace_back(1, 10, 10);
expected_tasks[i].emplace_back(3, 15, 25); expected_tasks[i].emplace_back(3, 15, 25);
......
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h"
namespace base {
namespace sequence_manager {
SimpleThreadImpl::SimpleThreadImpl(ThreadPoolManager* thread_pool_manager,
TimeTicks initial_time,
ThreadCallback callback)
: SimpleThread("TestThread"),
thread_pool_manager_(thread_pool_manager),
initial_time_(initial_time),
callback_(std::move(callback)) {
DCHECK(thread_pool_manager_);
}
void SimpleThreadImpl::Run() {
std::unique_ptr<ThreadManager> thread_manager =
std::make_unique<ThreadManager>(initial_time_,
thread_pool_manager_->processor());
thread_manager_ = thread_manager.get();
std::move(callback_).Run(thread_manager_);
thread_can_shutdown_.Wait();
}
SimpleThreadImpl::~SimpleThreadImpl() {
thread_can_shutdown_.Signal();
Join();
}
ThreadManager* SimpleThreadImpl::thread_manager() const {
return thread_manager_;
}
} // namespace sequence_manager
} // namespace base
...@@ -2,48 +2,55 @@ ...@@ -2,48 +2,55 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file // found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SIMPLE_THREAD_IMPL_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_SIMPLE_THREAD_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SIMPLE_THREAD_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_SIMPLE_THREAD_IMPL_H_
#include "base/callback.h" #include "base/callback.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "base/threading/simple_thread.h" #include "base/threading/simple_thread.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/base/thread_data.h"
namespace base { namespace base {
namespace sequence_manager { namespace sequence_manager {
class ThreadPoolManager;
class ThreadManager;
// Used by the ThreadPoolManager to create threads that do not have an // Used by the ThreadPoolManager to create threads that do not have an
// associated message loop, since we want to use base::TestMockTimeTaskRunner to // associated message loop, since we want to use base::TestMockTimeTaskRunner to
// control the task execution and the clock of the thread. // control the task execution and the clock of the thread.
class PLATFORM_EXPORT SimpleThreadImpl : public SimpleThread { class PLATFORM_EXPORT SimpleThreadImpl : public SimpleThread {
public: public:
using ThreadCallback = base::OnceCallback<void(ThreadData*)>; using ThreadCallback = base::OnceCallback<void(ThreadManager*)>;
SimpleThreadImpl(ThreadCallback callback, TimeTicks initial_time); SimpleThreadImpl(ThreadPoolManager* thread_pool_manager,
TimeTicks initial_time,
ThreadCallback callback);
~SimpleThreadImpl() override; ~SimpleThreadImpl() override;
ThreadData* thread_data() const; ThreadManager* thread_manager() const;
private: private:
// This doesn't terminate until |this| object is destructed. // This doesn't terminate until |this| object is destructed.
void Run() override; void Run() override;
ThreadCallback callback_; // Owner of this class.
ThreadPoolManager* thread_pool_manager_;
// Time in which the thread is created. // Time in which the thread is created.
TimeTicks initial_time_; TimeTicks initial_time_;
// The object pointed to by |thread_data_| is created and destructed from the // The object pointed to by |thread_manager_| is created and destructed from
// Run function. This is necessary since it has to be constructed from the // the Run function. This is necessary since it has to be constructed from the
// thread it should be bound to and destructed from the same thread. // thread it should be bound to and destructed from the same thread.
ThreadData* thread_data_; ThreadManager* thread_manager_;
// Used by the Run function to only terminate when |this| is destructed, and // Used by the Run function to only terminate when |this| is destructed, and
// this is used so that |thread_data_| will live as long as |this|. // this is used so that |thread_data_| will live as long as |this|.
WaitableEvent thread_can_shutdown_; WaitableEvent thread_can_shutdown_;
ThreadCallback callback_;
}; };
} // namespace sequence_manager } // namespace sequence_manager
......
...@@ -2,26 +2,64 @@ ...@@ -2,26 +2,64 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file // found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_DATA_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_THREAD_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_DATA_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_THREAD_MANAGER_H_
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h" #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/task/sequence_manager/test/test_task_queue.h" #include "base/task/sequence_manager/test/test_task_queue.h"
#include "base/test/test_mock_time_task_runner.h" #include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/proto/sequence_manager_test_description.pb.h"
#include "third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h"
namespace base { namespace base {
namespace sequence_manager { namespace sequence_manager {
class PLATFORM_EXPORT ThreadData { // Used by the SequenceManagerFuzzerProcessor to execute actions on a thread.
class PLATFORM_EXPORT ThreadManager {
public: public:
// |initial_time| is the time in which |this| was instantiated.
ThreadManager(TimeTicks initial_time,
SequenceManagerFuzzerProcessor* processor);
~ThreadManager();
// Returns the time of the underlying task runner.
TimeTicks NowTicks();
// Returns the delay of the oldest pending task on the thread |this| is bound
// to.
TimeDelta NextPendingTaskDelay();
// Advances the clock of the underlying task runner by |delta|.
void AdvanceMockTickClock(TimeDelta delta);
// Used to create a thread and register it with the thread pool manager owned
// by |processor_|.
void ExecuteCreateThreadAction(
uint64_t action_id,
const SequenceManagerTestDescription::CreateThreadAction& action);
// Used by the thread pool manager owned by |processor_| to execute the
// thread.
void ExecuteThread(
const google::protobuf::RepeatedPtrField<
SequenceManagerTestDescription::Action>& initial_thread_actions);
const std::vector<SequenceManagerFuzzerProcessor::TaskForTest>&
ordered_tasks() const;
const std::vector<SequenceManagerFuzzerProcessor::ActionForTest>&
ordered_actions() const;
protected:
struct TaskQueueWithVoters { struct TaskQueueWithVoters {
explicit TaskQueueWithVoters(scoped_refptr<TestTaskQueue> task_queue) explicit TaskQueueWithVoters(scoped_refptr<TestTaskQueue> task_queue)
: queue(std::move(task_queue)){}; : queue(std::move(task_queue)){};
...@@ -30,10 +68,58 @@ class PLATFORM_EXPORT ThreadData { ...@@ -30,10 +68,58 @@ class PLATFORM_EXPORT ThreadData {
std::vector<std::unique_ptr<TaskQueue::QueueEnabledVoter>> voters; std::vector<std::unique_ptr<TaskQueue::QueueEnabledVoter>> voters;
}; };
// |initial_time| is the time in which |this| was instantiated. class Task {
explicit ThreadData(TimeTicks initial_time); public:
explicit Task(ThreadManager* thread_manager);
~Task() = default;
void Execute(const SequenceManagerTestDescription::Task& task);
~ThreadData(); bool is_running;
// Should outlive |this|.
ThreadManager* thread_manager_;
base::WeakPtrFactory<Task> weak_ptr_factory_;
};
void RunAction(const SequenceManagerTestDescription::Action& action);
void ExecuteCreateTaskQueueAction(
uint64_t action_id,
const SequenceManagerTestDescription::CreateTaskQueueAction& action);
void ExecutePostDelayedTaskAction(
uint64_t action_id,
const SequenceManagerTestDescription::PostDelayedTaskAction& action);
void ExecuteSetQueuePriorityAction(
uint64_t action_id,
const SequenceManagerTestDescription::SetQueuePriorityAction& action);
void ExecuteSetQueueEnabledAction(
uint64_t action_id,
const SequenceManagerTestDescription::SetQueueEnabledAction& action);
void ExecuteCreateQueueVoterAction(
uint64_t action_id,
const SequenceManagerTestDescription::CreateQueueVoterAction& action);
void ExecuteShutdownTaskQueueAction(
uint64_t action_id,
const SequenceManagerTestDescription::ShutdownTaskQueueAction& action);
void ExecuteCancelTaskAction(
uint64_t action_id,
const SequenceManagerTestDescription::CancelTaskAction& action);
void ExecuteInsertFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::InsertFenceAction& action);
void ExecuteRemoveFenceAction(
uint64_t action_id,
const SequenceManagerTestDescription::RemoveFenceAction& action);
private:
using ActionForTest = SequenceManagerFuzzerProcessor::ActionForTest;
using TaskForTest = SequenceManagerFuzzerProcessor::TaskForTest;
void ExecuteTask(const SequenceManagerTestDescription::Task& task);
// Used to delete |task| from |pending_tasks_|.
void DeleteTask(Task* task);
// Bound to the thread in which this object was instantiated. Used to // Bound to the thread in which this object was instantiated. Used to
// control the clock of the sequence manager. // control the clock of the sequence manager.
...@@ -48,8 +134,7 @@ class PLATFORM_EXPORT ThreadData { ...@@ -48,8 +134,7 @@ class PLATFORM_EXPORT ThreadData {
// Used to be able to cancel pending tasks from the sequence manager. For // Used to be able to cancel pending tasks from the sequence manager. For
// testing purposes, this should follow the order in which the tasks were // testing purposes, this should follow the order in which the tasks were
// posted to the thread in which |this| was instantiated. // posted to the thread in which |this| was instantiated.
std::vector<std::unique_ptr<SequenceManagerFuzzerProcessor::Task>> std::vector<std::unique_ptr<Task>> pending_tasks_;
pending_tasks_;
// For Testing. Used to log tasks in their order of execution on the // For Testing. Used to log tasks in their order of execution on the
// thread in which |this| was instantiated. // thread in which |this| was instantiated.
...@@ -59,6 +144,10 @@ class PLATFORM_EXPORT ThreadData { ...@@ -59,6 +144,10 @@ class PLATFORM_EXPORT ThreadData {
// thread in which |this| was instantiated. // thread in which |this| was instantiated.
std::vector<SequenceManagerFuzzerProcessor::ActionForTest> ordered_actions_; std::vector<SequenceManagerFuzzerProcessor::ActionForTest> ordered_actions_;
// Outlives this class. |processor_| owns a thread pool manager that creates
// threads.
SequenceManagerFuzzerProcessor* const processor_;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
}; };
......
#include "third_party/blink/renderer/platform/scheduler/base/thread_pool_manager.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_pool_manager.h"
#include <algorithm> #include <algorithm>
#include "base/bind.h" #include "base/bind.h"
#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/sequence_manager_fuzzer_processor.h"
#include "third_party/blink/renderer/platform/scheduler/base/simple_thread_impl.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/simple_thread_impl.h"
#include "third_party/blink/renderer/platform/scheduler/base/thread_data.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/thread_manager.h"
namespace base { namespace base {
namespace sequence_manager { namespace sequence_manager {
...@@ -37,9 +37,9 @@ void ThreadPoolManager::CreateThread( ...@@ -37,9 +37,9 @@ void ThreadPoolManager::CreateThread(
{ {
AutoLock lock(lock_); AutoLock lock(lock_);
threads_.push_back(std::make_unique<SimpleThreadImpl>( threads_.push_back(std::make_unique<SimpleThreadImpl>(
this, time,
BindOnce(&ThreadPoolManager::StartThread, Unretained(this), BindOnce(&ThreadPoolManager::StartThread, Unretained(this),
initial_thread_actions), initial_thread_actions)));
time));
thread = threads_.back().get(); thread = threads_.back().get();
} }
thread->Start(); thread->Start();
...@@ -48,30 +48,26 @@ void ThreadPoolManager::CreateThread( ...@@ -48,30 +48,26 @@ void ThreadPoolManager::CreateThread(
void ThreadPoolManager::StartThread( void ThreadPoolManager::StartThread(
const google::protobuf::RepeatedPtrField< const google::protobuf::RepeatedPtrField<
SequenceManagerTestDescription::Action>& initial_thread_actions, SequenceManagerTestDescription::Action>& initial_thread_actions,
ThreadData* thread_data) { ThreadManager* thread_manager) {
{ {
AutoLock lock(lock_); AutoLock lock(lock_);
while (!initial_threads_created_) while (!initial_threads_created_)
ready_to_execute_threads_.Wait(); ready_to_execute_threads_.Wait();
} }
processor_->ExecuteThread(thread_data, initial_thread_actions); thread_manager->ExecuteThread(initial_thread_actions);
} }
void ThreadPoolManager::AdvanceClockSynchronouslyByPendingTaskDelay( void ThreadPoolManager::AdvanceClockSynchronouslyByPendingTaskDelay(
ThreadData* thread_data) { ThreadManager* thread_manager) {
DCHECK_CALLED_ON_VALID_THREAD(thread_data->thread_checker_);
ThreadReadyToComputeTime(); ThreadReadyToComputeTime();
{ {
AutoLock lock(lock_); AutoLock lock(lock_);
while (threads_waiting_to_compute_time_ != threads_.size()) while (threads_waiting_to_compute_time_ != threads_.size())
ready_to_compute_time_.Wait(); ready_to_compute_time_.Wait();
next_time_ = std::min( next_time_ =
next_time_, std::min(next_time_, thread_manager->NowTicks() +
thread_data->test_task_runner_->GetMockTickClock()->NowTicks() + thread_manager->NextPendingTaskDelay());
std::max(TimeDelta::FromMilliseconds(0),
thread_data->test_task_runner_->NextPendingTaskDelay()));
threads_waiting_to_advance_time_++; threads_waiting_to_advance_time_++;
if (threads_waiting_to_advance_time_ == threads_.size()) { if (threads_waiting_to_advance_time_ == threads_.size()) {
threads_waiting_to_compute_time_ = 0; threads_waiting_to_compute_time_ = 0;
...@@ -79,10 +75,11 @@ void ThreadPoolManager::AdvanceClockSynchronouslyByPendingTaskDelay( ...@@ -79,10 +75,11 @@ void ThreadPoolManager::AdvanceClockSynchronouslyByPendingTaskDelay(
} }
} }
AdvanceThreadClock(thread_data); AdvanceThreadClock(thread_manager);
} }
void ThreadPoolManager::AdvanceClockSynchronouslyToTime(ThreadData* thread_data, void ThreadPoolManager::AdvanceClockSynchronouslyToTime(
ThreadManager* thread_manager,
TimeTicks time) { TimeTicks time) {
ThreadReadyToComputeTime(); ThreadReadyToComputeTime();
{ {
...@@ -96,7 +93,7 @@ void ThreadPoolManager::AdvanceClockSynchronouslyToTime(ThreadData* thread_data, ...@@ -96,7 +93,7 @@ void ThreadPoolManager::AdvanceClockSynchronouslyToTime(ThreadData* thread_data,
ready_to_advance_time_.Broadcast(); ready_to_advance_time_.Broadcast();
} }
} }
AdvanceThreadClock(thread_data); AdvanceThreadClock(thread_manager);
} }
void ThreadPoolManager::ThreadReadyToComputeTime() { void ThreadPoolManager::ThreadReadyToComputeTime() {
...@@ -110,13 +107,11 @@ void ThreadPoolManager::ThreadReadyToComputeTime() { ...@@ -110,13 +107,11 @@ void ThreadPoolManager::ThreadReadyToComputeTime() {
} }
} }
void ThreadPoolManager::AdvanceThreadClock(ThreadData* thread_data) { void ThreadPoolManager::AdvanceThreadClock(ThreadManager* thread_manager) {
AutoLock lock(lock_); AutoLock lock(lock_);
while (threads_waiting_to_advance_time_ != threads_.size()) while (threads_waiting_to_advance_time_ != threads_.size())
ready_to_advance_time_.Wait(); ready_to_advance_time_.Wait();
thread_data->test_task_runner_->AdvanceMockTickClock( thread_manager->AdvanceMockTickClock(next_time_ - thread_manager->NowTicks());
next_time_ -
thread_data->test_task_runner_->GetMockTickClock()->NowTicks());
threads_ready_for_next_round_++; threads_ready_for_next_round_++;
if (threads_ready_for_next_round_ == threads_.size()) { if (threads_ready_for_next_round_ == threads_.size()) {
threads_waiting_to_advance_time_ = 0; threads_waiting_to_advance_time_ = 0;
...@@ -153,9 +148,13 @@ void ThreadPoolManager::ThreadDone() { ...@@ -153,9 +148,13 @@ void ThreadPoolManager::ThreadDone() {
} }
const std::vector<std::unique_ptr<SimpleThreadImpl>>& const std::vector<std::unique_ptr<SimpleThreadImpl>>&
ThreadPoolManager::threads() { ThreadPoolManager::threads() const {
return threads_; return threads_;
} }
SequenceManagerFuzzerProcessor* ThreadPoolManager::processor() const {
return processor_;
}
} // namespace sequence_manager } // namespace sequence_manager
} // namespace base } // namespace base
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file // found in the LICENSE file
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_POOL_MANAGER_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_THREAD_POOL_MANAGER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_POOL_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_TEST_FUZZER_THREAD_POOL_MANAGER_H_
#include <memory> #include <memory>
#include <vector> #include <vector>
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" #include "third_party/blink/renderer/platform/scheduler/test/fuzzer/proto/sequence_manager_test_description.pb.h"
namespace base { namespace base {
namespace sequence_manager { namespace sequence_manager {
class SequenceManagerFuzzerProcessor; class SequenceManagerFuzzerProcessor;
class SimpleThreadImpl; class SimpleThreadImpl;
class ThreadData; class ThreadManager;
// Used by the SequenceManagerFuzzerProcessor to manage threads and synchronize // Used by the SequenceManagerFuzzerProcessor to manage threads and synchronize
// their clocks. // their clocks.
...@@ -28,23 +28,24 @@ class PLATFORM_EXPORT ThreadPoolManager { ...@@ -28,23 +28,24 @@ class PLATFORM_EXPORT ThreadPoolManager {
explicit ThreadPoolManager(SequenceManagerFuzzerProcessor* processor); explicit ThreadPoolManager(SequenceManagerFuzzerProcessor* processor);
~ThreadPoolManager(); ~ThreadPoolManager();
// |time| is the virtual time in which the thread is created. The virtual time // |initial_time| is the time in which the thread is created.
// is controlled by |this| and synchronized for all the threads it owns.
void CreateThread( void CreateThread(
const google::protobuf::RepeatedPtrField< const google::protobuf::RepeatedPtrField<
SequenceManagerTestDescription::Action>& initial_thread_actions, SequenceManagerTestDescription::Action>& initial_thread_actions,
TimeTicks time); TimeTicks initial_time);
// Advances the mock tick clock of all the threads synchronously. // Advances the mock tick clock of all the threads synchronously.
// Note that this doesn't guarantee advancing the thread's clock to |time|. // Note that this doesn't guarantee advancing the thread's clock to |time|.
// The clock is advanced to the minimum desired time of all the owned threads. // The clock is advanced to the minimum desired time of all the owned threads.
void AdvanceClockSynchronouslyToTime(ThreadData* thread_data, TimeTicks time); void AdvanceClockSynchronouslyToTime(ThreadManager* thread_manager,
TimeTicks time);
// Advances the mock tick clock of all the threads synchronously. // Advances the mock tick clock of all the threads synchronously.
// Note that this doesn't guarantee advancing the thread's clock by the next // Note that this doesn't guarantee advancing the thread's clock by the next
// pending task delay. The clock is advanced to the minimum desired time of // pending task delay. The clock is advanced to the minimum desired time of
// all the owned threads. // all the owned threads.
void AdvanceClockSynchronouslyByPendingTaskDelay(ThreadData* thread_data); void AdvanceClockSynchronouslyByPendingTaskDelay(
ThreadManager* thread_manager);
// Used by a thread to notify the thread manager that it is done executing the // Used by a thread to notify the thread manager that it is done executing the
// thread actions passed to ThreadPoolManager::CreateThread. // thread actions passed to ThreadPoolManager::CreateThread.
...@@ -57,13 +58,15 @@ class PLATFORM_EXPORT ThreadPoolManager { ...@@ -57,13 +58,15 @@ class PLATFORM_EXPORT ThreadPoolManager {
// the threads are not terminated until |this| gets destructed. // the threads are not terminated until |this| gets destructed.
void WaitForAllThreads(); void WaitForAllThreads();
const std::vector<std::unique_ptr<SimpleThreadImpl>>& threads(); const std::vector<std::unique_ptr<SimpleThreadImpl>>& threads() const;
SequenceManagerFuzzerProcessor* processor() const;
private: private:
void StartThread( void StartThread(
const google::protobuf::RepeatedPtrField< const google::protobuf::RepeatedPtrField<
SequenceManagerTestDescription::Action>& initial_thread_actions, SequenceManagerTestDescription::Action>& initial_thread_actions,
ThreadData* thread_data); ThreadManager* thread_manager);
// Helper function used by AdvanceClockSynchronouslyToTime and // Helper function used by AdvanceClockSynchronouslyToTime and
// AdvanceClockSynchronouslyByPendingTaskDelay to notify the manager when all // AdvanceClockSynchronouslyByPendingTaskDelay to notify the manager when all
...@@ -72,9 +75,9 @@ class PLATFORM_EXPORT ThreadPoolManager { ...@@ -72,9 +75,9 @@ class PLATFORM_EXPORT ThreadPoolManager {
// Helper function used by AdvanceClockSynchronouslyToTime and // Helper function used by AdvanceClockSynchronouslyToTime and
// AdvanceClockSynchronouslyByPendingTaskDelay to advance the thread's clock // AdvanceClockSynchronouslyByPendingTaskDelay to advance the thread's clock
// to |next_time_|. Note that this function waits until all owned threads have // to |next_time_|. Note that this function waits until all threads have
// voted on the value of |next_time_|. // voted on the value of |next_time_|.
void AdvanceThreadClock(ThreadData* thread_data); void AdvanceThreadClock(ThreadManager* thread_manager);
// Owner of this class. // Owner of this class.
SequenceManagerFuzzerProcessor* const processor_; SequenceManagerFuzzerProcessor* const processor_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment