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

Side by Side Diff: base/task_scheduler/task_tracker.cc

Issue 1705943002: TaskScheduler [5/9] Task Tracker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s_3_pq
Patch Set: CR robliao #61 Created 4 years, 8 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 unified diff | Download patch
« no previous file with comments | « base/task_scheduler/task_tracker.h ('k') | base/task_scheduler/task_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/task_scheduler/task_tracker.h"
6
7 #include "base/callback.h"
8 #include "base/debug/task_annotator.h"
9 #include "base/metrics/histogram_macros.h"
10
11 namespace base {
12 namespace internal {
13
14 namespace {
15
16 const char kQueueFunctionName[] = "base::PostTask";
17
18 // Upper bound for the
19 // TaskScheduler.BlockShutdownTasksPostedDuringShutdown histogram.
20 const HistogramBase::Sample kMaxBlockShutdownTasksPostedDuringShutdown = 1000;
21
22 void RecordNumBlockShutdownTasksPostedDuringShutdown(
23 HistogramBase::Sample value) {
24 UMA_HISTOGRAM_CUSTOM_COUNTS(
25 "TaskScheduler.BlockShutdownTasksPostedDuringShutdown", value, 1,
26 kMaxBlockShutdownTasksPostedDuringShutdown, 50);
27 }
28
29 } // namespace
30
31 TaskTracker::TaskTracker() = default;
32 TaskTracker::~TaskTracker() = default;
33
34 void TaskTracker::Shutdown() {
35 AutoSchedulerLock auto_lock(lock_);
36
37 // This method should only be called once.
38 DCHECK(!shutdown_completed_);
39 DCHECK(!shutdown_cv_);
40
41 shutdown_cv_ = lock_.CreateConditionVariable();
42
43 // Wait until the number of tasks blocking shutdown is zero.
44 while (num_tasks_blocking_shutdown_ != 0)
45 shutdown_cv_->Wait();
46
47 shutdown_cv_.reset();
48 shutdown_completed_ = true;
49
50 // Record the TaskScheduler.BlockShutdownTasksPostedDuringShutdown if less
51 // than |kMaxBlockShutdownTasksPostedDuringShutdown| BLOCK_SHUTDOWN tasks were
52 // posted during shutdown. Otherwise, the histogram has already been recorded
53 // in BeforePostTask().
54 if (num_block_shutdown_tasks_posted_during_shutdown_ <
55 kMaxBlockShutdownTasksPostedDuringShutdown) {
56 RecordNumBlockShutdownTasksPostedDuringShutdown(
57 num_block_shutdown_tasks_posted_during_shutdown_);
58 }
59 }
60
61 void TaskTracker::PostTask(
62 const Callback<void(scoped_ptr<Task>)>& post_task_callback,
63 scoped_ptr<Task> task) {
64 DCHECK(!post_task_callback.is_null());
65 DCHECK(task);
66
67 if (!BeforePostTask(task->traits.shutdown_behavior()))
68 return;
69
70 debug::TaskAnnotator task_annotator;
71 task_annotator.DidQueueTask(kQueueFunctionName, *task);
72
73 post_task_callback.Run(std::move(task));
74 }
75
76 void TaskTracker::RunTask(const Task* task) {
77 DCHECK(task);
78
79 const TaskShutdownBehavior shutdown_behavior =
80 task->traits.shutdown_behavior();
81 if (!BeforeRunTask(shutdown_behavior))
82 return;
83
84 debug::TaskAnnotator task_annotator;
85 task_annotator.RunTask(kQueueFunctionName, *task);
86
87 AfterRunTask(shutdown_behavior);
88 }
89
90 bool TaskTracker::IsShuttingDownForTesting() const {
91 AutoSchedulerLock auto_lock(lock_);
92 return !!shutdown_cv_;
93 }
94
95 bool TaskTracker::BeforePostTask(TaskShutdownBehavior shutdown_behavior) {
96 AutoSchedulerLock auto_lock(lock_);
97
98 if (shutdown_completed_) {
99 // A BLOCK_SHUTDOWN task posted after shutdown has completed is an ordering
100 // bug. This DCHECK aims to catch those early.
101 DCHECK_NE(shutdown_behavior, TaskShutdownBehavior::BLOCK_SHUTDOWN);
102
103 // No task is allowed to be posted after shutdown.
104 return false;
105 }
106
107 if (shutdown_behavior == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
108 // BLOCK_SHUTDOWN tasks block shutdown between the moment they are posted
109 // and the moment they complete their execution.
110 ++num_tasks_blocking_shutdown_;
111
112 if (shutdown_cv_) {
113 ++num_block_shutdown_tasks_posted_during_shutdown_;
114
115 if (num_block_shutdown_tasks_posted_during_shutdown_ ==
116 kMaxBlockShutdownTasksPostedDuringShutdown) {
117 // Record the TaskScheduler.BlockShutdownTasksPostedDuringShutdown
118 // histogram as soon as its upper bound is hit. That way, a value will
119 // be recorded even if an infinite number of BLOCK_SHUTDOWN tasks are
120 // posted, preventing shutdown to complete.
121 RecordNumBlockShutdownTasksPostedDuringShutdown(
122 num_block_shutdown_tasks_posted_during_shutdown_);
123 }
124 }
125
126 // A BLOCK_SHUTDOWN task is allowed to be posted iff shutdown hasn't
127 // completed.
128 return true;
129 }
130
131 // A non BLOCK_SHUTDOWN task is allowed to be posted iff shutdown hasn't
132 // started.
133 return !shutdown_cv_;
134 }
135
136 bool TaskTracker::BeforeRunTask(TaskShutdownBehavior shutdown_behavior) {
137 AutoSchedulerLock auto_lock(lock_);
138
139 if (shutdown_completed_) {
140 // Trying to run a BLOCK_SHUTDOWN task after shutdown has completed is
141 // unexpected as it either shouldn't have been posted if shutdown completed
142 // or should be blocking shutdown if it was posted before it did.
143 DCHECK_NE(shutdown_behavior, TaskShutdownBehavior::BLOCK_SHUTDOWN);
144
145 // A WorkerThread might extract a non BLOCK_SHUTDOWN task from a
146 // PriorityQueue after shutdown. It shouldn't be allowed to run it.
147 return false;
148 }
149
150 switch (shutdown_behavior) {
151 case TaskShutdownBehavior::BLOCK_SHUTDOWN:
152 DCHECK_GT(num_tasks_blocking_shutdown_, 0U);
153 return true;
154
155 case TaskShutdownBehavior::SKIP_ON_SHUTDOWN:
156 if (shutdown_cv_)
157 return false;
158
159 // SKIP_ON_SHUTDOWN tasks block shutdown while they are running.
160 ++num_tasks_blocking_shutdown_;
161 return true;
162
163 case TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN:
164 return !shutdown_cv_;
165 }
166
167 NOTREACHED();
168 return false;
169 }
170
171 void TaskTracker::AfterRunTask(TaskShutdownBehavior shutdown_behavior) {
172 if (shutdown_behavior == TaskShutdownBehavior::BLOCK_SHUTDOWN ||
173 shutdown_behavior == TaskShutdownBehavior::SKIP_ON_SHUTDOWN) {
174 AutoSchedulerLock auto_lock(lock_);
175 DCHECK_GT(num_tasks_blocking_shutdown_, 0U);
176 --num_tasks_blocking_shutdown_;
177 if (num_tasks_blocking_shutdown_ == 0 && shutdown_cv_)
178 shutdown_cv_->Signal();
179 }
180 }
181
182 } // namespace internal
183 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/task_tracker.h ('k') | base/task_scheduler/task_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698