summaryrefslogtreecommitdiffstats
path: root/cc/raster
diff options
context:
space:
mode:
authorericrk <ericrk@chromium.org>2016-02-24 13:17:10 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-24 21:18:12 +0000
commitf064193fe71b8b055d060adb10fbc4e3cca8c604 (patch)
treefacaf8736a0dde2c8cdb362b83a0441873a6cad0 /cc/raster
parent33895d99a4d329bd617013bcf4b49732c57d26f5 (diff)
downloadchromium_src-f064193fe71b8b055d060adb10fbc4e3cca8c604.zip
chromium_src-f064193fe71b8b055d060adb10fbc4e3cca8c604.tar.gz
chromium_src-f064193fe71b8b055d060adb10fbc4e3cca8c604.tar.bz2
Refactor signaling in RWP
A previous patch had moved RasterWorkerPool to make heavy use of broadcast in order to simplify logic a bit. It turns out that broadcast is not ideal in performance critical situations, as it increases lock contention (see https://code.google.com/p/chromium/codesearch#chromium/src/base/synchronization/condition_variable.h&l=34). This change removes all uses of broadcast other than in Shutdown, where performance is less of a concern and we actually need all threads to wake up. To achieve this, we need to re-factor RWP to use: - N foreground threads - 1 background thread rather than N threads which may be able to run foreground/background tasks. In order to ensure that we don't overload the system, this change introduces a limiting system where the background priority thread can only run tasks if no other threads are doing so. BUG= CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1666283002 Cr-Commit-Position: refs/heads/master@{#377379}
Diffstat (limited to 'cc/raster')
-rw-r--r--cc/raster/task_graph_work_queue.cc26
-rw-r--r--cc/raster/task_graph_work_queue.h17
2 files changed, 33 insertions, 10 deletions
diff --git a/cc/raster/task_graph_work_queue.cc b/cc/raster/task_graph_work_queue.cc
index 2947402..f4368e1 100644
--- a/cc/raster/task_graph_work_queue.cc
+++ b/cc/raster/task_graph_work_queue.cc
@@ -97,9 +97,11 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) {
continue;
// Skip if already running.
- if (std::find(task_namespace.running_tasks.begin(),
- task_namespace.running_tasks.end(),
- node.task) != task_namespace.running_tasks.end())
+ if (std::any_of(task_namespace.running_tasks.begin(),
+ task_namespace.running_tasks.end(),
+ [&node](const CategorizedTask& task) {
+ return task.second == node.task;
+ }))
continue;
task_namespace.ready_to_run_tasks[node.category].push_back(PrioritizedTask(
@@ -127,9 +129,11 @@ void TaskGraphWorkQueue::ScheduleTasks(NamespaceToken token, TaskGraph* graph) {
continue;
// Skip if already running.
- if (std::find(task_namespace.running_tasks.begin(),
- task_namespace.running_tasks.end(),
- node.task) != task_namespace.running_tasks.end())
+ if (std::any_of(task_namespace.running_tasks.begin(),
+ task_namespace.running_tasks.end(),
+ [&node](const CategorizedTask& task) {
+ return task.second == node.task;
+ }))
continue;
DCHECK(std::find(task_namespace.completed_tasks.begin(),
@@ -195,7 +199,8 @@ TaskGraphWorkQueue::PrioritizedTask TaskGraphWorkQueue::GetNextTaskToRun(
}
// Add task to |running_tasks|.
- task_namespace->running_tasks.push_back(task.task);
+ task_namespace->running_tasks.push_back(
+ std::make_pair(task.category, task.task));
return task;
}
@@ -205,8 +210,11 @@ void TaskGraphWorkQueue::CompleteTask(const PrioritizedTask& completed_task) {
scoped_refptr<Task> task(completed_task.task);
// Remove task from |running_tasks|.
- auto it = std::find(task_namespace->running_tasks.begin(),
- task_namespace->running_tasks.end(), task);
+ auto it = std::find_if(task_namespace->running_tasks.begin(),
+ task_namespace->running_tasks.end(),
+ [&completed_task](const CategorizedTask& task) {
+ return task.second == completed_task.task;
+ });
DCHECK(it != task_namespace->running_tasks.end());
std::swap(*it, task_namespace->running_tasks.back());
task_namespace->running_tasks.pop_back();
diff --git a/cc/raster/task_graph_work_queue.h b/cc/raster/task_graph_work_queue.h
index 95d3c77..7fbd19b 100644
--- a/cc/raster/task_graph_work_queue.h
+++ b/cc/raster/task_graph_work_queue.h
@@ -46,6 +46,8 @@ class CC_EXPORT TaskGraphWorkQueue {
uint16_t priority;
};
+ using CategorizedTask = std::pair<uint16_t, scoped_refptr<Task>>;
+
// Helper classes and static methods used by dependent classes.
struct TaskNamespace {
typedef std::vector<TaskNamespace*> Vector;
@@ -64,7 +66,7 @@ class CC_EXPORT TaskGraphWorkQueue {
Task::Vector completed_tasks;
// This set contains all currently running tasks.
- Task::Vector running_tasks;
+ std::vector<CategorizedTask> running_tasks;
};
TaskGraphWorkQueue();
@@ -145,6 +147,19 @@ class CC_EXPORT TaskGraphWorkQueue {
return ready_to_run_namespaces_;
}
+ size_t NumRunningTasksForCategory(uint16_t category) const {
+ size_t count = 0;
+ for (const auto& task_namespace_entry : namespaces_) {
+ for (const auto& categorized_task :
+ task_namespace_entry.second.running_tasks) {
+ if (categorized_task.first == category) {
+ ++count;
+ }
+ }
+ }
+ return count;
+ }
+
// Helper function which ensures that graph dependencies were correctly
// configured.
static bool DependencyMismatch(const TaskGraph* graph);