OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/scheduler/base/task_queue_impl.h" | 5 #include "platform/scheduler/base/task_queue_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 // destructor calls UnregisterTaskQueue on all task queues. | 102 // destructor calls UnregisterTaskQueue on all task queues. |
103 DCHECK(any_thread().task_queue_manager == nullptr) | 103 DCHECK(any_thread().task_queue_manager == nullptr) |
104 << "UnregisterTaskQueue must be called first!"; | 104 << "UnregisterTaskQueue must be called first!"; |
105 #endif | 105 #endif |
106 } | 106 } |
107 | 107 |
108 TaskQueueImpl::Task::Task() | 108 TaskQueueImpl::Task::Task() |
109 : PendingTask(tracked_objects::Location(), | 109 : PendingTask(tracked_objects::Location(), |
110 base::Closure(), | 110 base::Closure(), |
111 base::TimeTicks(), | 111 base::TimeTicks(), |
112 true), | 112 true) { |
113 #ifndef NDEBUG | |
114 enqueue_order_set_(false), | |
115 #endif | |
116 enqueue_order_(0) { | |
117 sequence_num = 0; | 113 sequence_num = 0; |
118 } | 114 } |
119 | 115 |
120 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | 116 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, |
121 base::OnceClosure task, | 117 base::OnceClosure task, |
122 base::TimeTicks desired_run_time, | 118 EnqueueOrder enqueue_order, |
123 EnqueueOrder sequence_number, | |
124 bool nestable) | 119 bool nestable) |
125 : PendingTask(posted_from, std::move(task), desired_run_time, nestable), | 120 : PendingTask(posted_from, |
126 #ifndef NDEBUG | 121 std::move(task), |
127 enqueue_order_set_(false), | 122 enqueue_order.delayed_run_time, |
128 #endif | 123 nestable), |
129 enqueue_order_(0) { | |
130 sequence_num = sequence_number; | |
131 } | |
132 | |
133 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, | |
134 base::OnceClosure task, | |
135 base::TimeTicks desired_run_time, | |
136 EnqueueOrder sequence_number, | |
137 bool nestable, | |
138 EnqueueOrder enqueue_order) | |
139 : PendingTask(posted_from, std::move(task), desired_run_time, nestable), | |
140 #ifndef NDEBUG | |
141 enqueue_order_set_(true), | |
142 #endif | |
143 enqueue_order_(enqueue_order) { | 124 enqueue_order_(enqueue_order) { |
144 sequence_num = sequence_number; | 125 // Note: these properties are only used for tracing. |
| 126 sequence_num = static_cast<int>(enqueue_order.sequence_num); |
| 127 delayed_run_time = enqueue_order.delayed_run_time; |
145 } | 128 } |
146 | 129 |
147 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, | 130 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, |
148 TimeDomain* time_domain) | 131 TimeDomain* time_domain) |
149 : task_queue_manager(task_queue_manager), | 132 : task_queue_manager(task_queue_manager), |
150 time_domain(time_domain), | 133 time_domain(time_domain), |
151 observer(nullptr) {} | 134 observer(nullptr) {} |
152 | 135 |
153 TaskQueueImpl::AnyThread::~AnyThread() {} | 136 TaskQueueImpl::AnyThread::~AnyThread() {} |
154 | 137 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 const tracked_objects::Location& from_here, | 206 const tracked_objects::Location& from_here, |
224 base::OnceClosure task, | 207 base::OnceClosure task, |
225 TaskType task_type) { | 208 TaskType task_type) { |
226 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 | 209 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 |
227 // for details. | 210 // for details. |
228 CHECK(task); | 211 CHECK(task); |
229 base::AutoLock lock(any_thread_lock_); | 212 base::AutoLock lock(any_thread_lock_); |
230 if (!any_thread().task_queue_manager) | 213 if (!any_thread().task_queue_manager) |
231 return false; | 214 return false; |
232 | 215 |
233 EnqueueOrder sequence_number = | 216 EnqueueOrder enqueue_order = |
234 any_thread().task_queue_manager->GetNextSequenceNumber(); | 217 any_thread().task_queue_manager->GetNextEnqueueOrder(base::TimeTicks()); |
235 | 218 |
236 PushOntoImmediateIncomingQueueLocked(from_here, std::move(task), | 219 PushOntoImmediateIncomingQueueLocked(from_here, std::move(task), |
237 base::TimeTicks(), sequence_number, | 220 enqueue_order, |
238 task_type != TaskType::NON_NESTABLE); | 221 task_type != TaskType::NON_NESTABLE); |
239 return true; | 222 return true; |
240 } | 223 } |
241 | 224 |
242 bool TaskQueueImpl::PostDelayedTaskImpl( | 225 bool TaskQueueImpl::PostDelayedTaskImpl( |
243 const tracked_objects::Location& from_here, | 226 const tracked_objects::Location& from_here, |
244 base::OnceClosure task, | 227 base::OnceClosure task, |
245 base::TimeDelta delay, | 228 base::TimeDelta delay, |
246 TaskType task_type) { | 229 TaskType task_type) { |
247 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 | 230 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 |
248 // for details. | 231 // for details. |
249 CHECK(task); | 232 CHECK(task); |
250 DCHECK_GT(delay, base::TimeDelta()); | 233 DCHECK_GT(delay, base::TimeDelta()); |
251 if (base::PlatformThread::CurrentId() == thread_id_) { | 234 if (base::PlatformThread::CurrentId() == thread_id_) { |
252 // Lock-free fast path for delayed tasks posted from the main thread. | 235 // Lock-free fast path for delayed tasks posted from the main thread. |
253 if (!main_thread_only().task_queue_manager) | 236 if (!main_thread_only().task_queue_manager) |
254 return false; | 237 return false; |
255 | 238 |
256 EnqueueOrder sequence_number = | |
257 main_thread_only().task_queue_manager->GetNextSequenceNumber(); | |
258 | |
259 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); | 239 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
260 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; | 240 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; |
| 241 EnqueueOrder enqueue_order = |
| 242 main_thread_only().task_queue_manager->GetNextEnqueueOrder( |
| 243 time_domain_delayed_run_time); |
261 PushOntoDelayedIncomingQueueFromMainThread( | 244 PushOntoDelayedIncomingQueueFromMainThread( |
262 Task(from_here, std::move(task), time_domain_delayed_run_time, | 245 Task(from_here, std::move(task), enqueue_order, |
263 sequence_number, task_type != TaskType::NON_NESTABLE), | 246 task_type != TaskType::NON_NESTABLE), |
264 time_domain_now); | 247 time_domain_now); |
265 } else { | 248 } else { |
266 // NOTE posting a delayed task from a different thread is not expected to | 249 // NOTE posting a delayed task from a different thread is not expected to |
267 // be common. This pathway is less optimal than perhaps it could be | 250 // be common. This pathway is less optimal than perhaps it could be |
268 // because it causes two main thread tasks to be run. Should this | 251 // because it causes two main thread tasks to be run. Should this |
269 // assumption prove to be false in future, we may need to revisit this. | 252 // assumption prove to be false in future, we may need to revisit this. |
270 base::AutoLock lock(any_thread_lock_); | 253 base::AutoLock lock(any_thread_lock_); |
271 if (!any_thread().task_queue_manager) | 254 if (!any_thread().task_queue_manager) |
272 return false; | 255 return false; |
273 | 256 |
274 EnqueueOrder sequence_number = | |
275 any_thread().task_queue_manager->GetNextSequenceNumber(); | |
276 | |
277 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); | 257 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); |
278 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; | 258 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; |
| 259 EnqueueOrder enqueue_order = |
| 260 any_thread().task_queue_manager->GetNextEnqueueOrder( |
| 261 time_domain_delayed_run_time); |
279 PushOntoDelayedIncomingQueueLocked( | 262 PushOntoDelayedIncomingQueueLocked( |
280 Task(from_here, std::move(task), time_domain_delayed_run_time, | 263 Task(from_here, std::move(task), enqueue_order, |
281 sequence_number, task_type != TaskType::NON_NESTABLE)); | 264 task_type != TaskType::NON_NESTABLE)); |
282 } | 265 } |
283 return true; | 266 return true; |
284 } | 267 } |
285 | 268 |
286 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( | 269 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( |
287 Task pending_task, base::TimeTicks now) { | 270 Task pending_task, base::TimeTicks now) { |
288 DelayedWakeUp wake_up = pending_task.delayed_wake_up(); | 271 DelayedWakeUp wake_up = pending_task.delayed_wake_up(); |
289 main_thread_only().task_queue_manager->DidQueueTask(pending_task); | 272 main_thread_only().task_queue_manager->DidQueueTask(pending_task); |
290 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); | 273 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
291 | 274 |
292 // If |pending_task| is at the head of the queue, then make sure a wake-up | 275 // If |pending_task| is at the head of the queue, then make sure a wake-up |
293 // is requested if the queue is enabled. Note we still want to schedule a | 276 // is requested if the queue is enabled. Note we still want to schedule a |
294 // wake-up even if blocked by a fence, because we'd break throttling logic | 277 // wake-up even if blocked by a fence, because we'd break throttling logic |
295 // otherwise. | 278 // otherwise. |
296 DelayedWakeUp new_wake_up = | 279 DelayedWakeUp new_wake_up = |
297 main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); | 280 main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); |
298 if (wake_up.time == new_wake_up.time && | 281 if (wake_up.time == new_wake_up.time && |
299 wake_up.sequence_num == new_wake_up.sequence_num) { | 282 wake_up.sequence_num == new_wake_up.sequence_num) { |
300 ScheduleDelayedWorkInTimeDomain(now); | 283 ScheduleDelayedWorkInTimeDomain(now); |
301 } | 284 } |
302 | 285 |
303 TraceQueueSize(); | 286 TraceQueueSize(); |
304 } | 287 } |
305 | 288 |
306 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { | 289 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { |
307 any_thread().task_queue_manager->DidQueueTask(pending_task); | 290 any_thread().task_queue_manager->DidQueueTask(pending_task); |
308 | 291 |
309 int thread_hop_task_sequence_number = | 292 EnqueueOrder thread_hop_task_enqueue_order = |
310 any_thread().task_queue_manager->GetNextSequenceNumber(); | 293 any_thread().task_queue_manager->GetNextEnqueueOrder(base::TimeTicks()); |
311 PushOntoImmediateIncomingQueueLocked( | 294 PushOntoImmediateIncomingQueueLocked( |
312 FROM_HERE, | 295 FROM_HERE, |
313 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, | 296 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, |
314 base::Passed(&pending_task)), | 297 base::Passed(&pending_task)), |
315 base::TimeTicks(), | 298 thread_hop_task_enqueue_order, false); |
316 thread_hop_task_sequence_number, | |
317 false); | |
318 } | 299 } |
319 | 300 |
320 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { | 301 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { |
321 DCHECK(main_thread_checker_.CalledOnValidThread()); | 302 DCHECK(main_thread_checker_.CalledOnValidThread()); |
322 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; | 303 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; |
323 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); | 304 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); |
324 if (delayed_run_time <= time_domain_now) { | 305 if (delayed_run_time <= time_domain_now) { |
325 // If |delayed_run_time| is in the past then push it onto the work queue | 306 // If |delayed_run_time| is in the past then push it onto the work queue |
326 // immediately. To ensure the right task ordering we need to temporarily | 307 // immediately. To ensure the right task ordering we need to temporarily |
327 // push it onto the |delayed_incoming_queue|. | 308 // push it onto the |delayed_incoming_queue|. |
328 delayed_run_time = time_domain_now; | 309 delayed_run_time = time_domain_now; |
329 pending_task.delayed_run_time = time_domain_now; | 310 pending_task.delayed_run_time = time_domain_now; |
330 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); | 311 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); |
331 LazyNow lazy_now(time_domain_now); | 312 LazyNow lazy_now(time_domain_now); |
332 WakeUpForDelayedWork(&lazy_now); | 313 WakeUpForDelayedWork(&lazy_now); |
333 } else { | 314 } else { |
334 // If |delayed_run_time| is in the future we can queue it as normal. | 315 // If |delayed_run_time| is in the future we can queue it as normal. |
335 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), | 316 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), |
336 time_domain_now); | 317 time_domain_now); |
337 } | 318 } |
338 TraceQueueSize(); | 319 TraceQueueSize(); |
339 } | 320 } |
340 | 321 |
341 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( | 322 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( |
342 const tracked_objects::Location& posted_from, | 323 const tracked_objects::Location& posted_from, |
343 base::OnceClosure task, | 324 base::OnceClosure task, |
344 base::TimeTicks desired_run_time, | 325 EnqueueOrder enqueue_order, |
345 EnqueueOrder sequence_number, | |
346 bool nestable) { | 326 bool nestable) { |
347 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make | 327 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make |
348 // it run. | 328 // it run. |
349 bool was_immediate_incoming_queue_empty; | 329 bool was_immediate_incoming_queue_empty; |
350 | 330 |
351 { | 331 { |
352 base::AutoLock lock(immediate_incoming_queue_lock_); | 332 base::AutoLock lock(immediate_incoming_queue_lock_); |
353 was_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); | 333 was_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); |
354 immediate_incoming_queue().emplace_back(posted_from, std::move(task), | 334 immediate_incoming_queue().emplace_back(posted_from, std::move(task), |
355 desired_run_time, sequence_number, | 335 enqueue_order, nestable); |
356 nestable, sequence_number); | |
357 any_thread().task_queue_manager->DidQueueTask( | 336 any_thread().task_queue_manager->DidQueueTask( |
358 immediate_incoming_queue().back()); | 337 immediate_incoming_queue().back()); |
359 } | 338 } |
360 | 339 |
361 if (was_immediate_incoming_queue_empty) { | 340 if (was_immediate_incoming_queue_empty) { |
362 // However there's no point posting a DoWork for a blocked queue. NB we can | 341 // However there's no point posting a DoWork for a blocked queue. NB we can |
363 // only tell if it's disabled from the main thread. | 342 // only tell if it's disabled from the main thread. |
364 bool queue_is_blocked = | 343 bool queue_is_blocked = |
365 RunsTasksOnCurrentThread() && | 344 RunsTasksOnCurrentThread() && |
366 (!IsQueueEnabled() || main_thread_only().current_fence); | 345 (!IsQueueEnabled() || main_thread_only().current_fence); |
367 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( | 346 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( |
368 this, sequence_number, queue_is_blocked); | 347 this, enqueue_order, queue_is_blocked); |
369 if (any_thread().observer) | 348 if (any_thread().observer) |
370 any_thread().observer->OnQueueNextWakeUpChanged(this, desired_run_time); | 349 any_thread().observer->OnQueueNextWakeUpChanged( |
| 350 this, enqueue_order.delayed_run_time); |
371 } | 351 } |
372 | 352 |
373 TraceQueueSize(); | 353 TraceQueueSize(); |
374 } | 354 } |
375 | 355 |
376 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { | 356 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { |
377 if (!main_thread_only().immediate_work_queue->Empty()) | 357 if (!main_thread_only().immediate_work_queue->Empty()) |
378 return; | 358 return; |
379 | 359 |
380 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue(); | 360 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 // have been canceled. | 423 // have been canceled. |
444 while (!main_thread_only().delayed_incoming_queue.empty()) { | 424 while (!main_thread_only().delayed_incoming_queue.empty()) { |
445 Task& task = | 425 Task& task = |
446 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); | 426 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); |
447 if (task.task.IsCancelled()) { | 427 if (task.task.IsCancelled()) { |
448 main_thread_only().delayed_incoming_queue.pop(); | 428 main_thread_only().delayed_incoming_queue.pop(); |
449 continue; | 429 continue; |
450 } | 430 } |
451 if (task.delayed_run_time > lazy_now->Now()) | 431 if (task.delayed_run_time > lazy_now->Now()) |
452 break; | 432 break; |
453 task.set_enqueue_order( | |
454 main_thread_only().task_queue_manager->GetNextSequenceNumber()); | |
455 main_thread_only().delayed_work_queue->Push(std::move(task)); | 433 main_thread_only().delayed_work_queue->Push(std::move(task)); |
456 main_thread_only().delayed_incoming_queue.pop(); | 434 main_thread_only().delayed_incoming_queue.pop(); |
457 } | 435 } |
458 | 436 |
459 // Make sure the next wake up is scheduled. | 437 // Make sure the next wake up is scheduled. |
460 if (!main_thread_only().delayed_incoming_queue.empty()) { | 438 if (!main_thread_only().delayed_incoming_queue.empty()) { |
461 return main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); | 439 return main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); |
462 } | 440 } |
463 | 441 |
464 return base::nullopt; | 442 return base::nullopt; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 | 596 |
619 void TaskQueueImpl::SetBlameContext( | 597 void TaskQueueImpl::SetBlameContext( |
620 base::trace_event::BlameContext* blame_context) { | 598 base::trace_event::BlameContext* blame_context) { |
621 main_thread_only().blame_context = blame_context; | 599 main_thread_only().blame_context = blame_context; |
622 } | 600 } |
623 | 601 |
624 void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { | 602 void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { |
625 if (!main_thread_only().task_queue_manager) | 603 if (!main_thread_only().task_queue_manager) |
626 return; | 604 return; |
627 | 605 |
628 EnqueueOrder previous_fence = main_thread_only().current_fence; | 606 SequenceNumber previous_fence = main_thread_only().current_fence; |
629 main_thread_only().current_fence = | 607 main_thread_only().current_fence = |
630 position == TaskQueue::InsertFencePosition::NOW | 608 position == TaskQueue::InsertFencePosition::NOW |
631 ? main_thread_only().task_queue_manager->GetNextSequenceNumber() | 609 ? main_thread_only() |
632 : static_cast<EnqueueOrder>(EnqueueOrderValues::BLOCKING_FENCE); | 610 .task_queue_manager->GetNextEnqueueOrder(base::TimeTicks()) |
| 611 .sequence_num |
| 612 : static_cast<SequenceNumber>( |
| 613 EnqueueOrderSequenceNumberValues::BLOCKING_FENCE); |
633 | 614 |
634 // Tasks posted after this point will have a strictly higher enqueue order | 615 // Tasks posted after this point will have a strictly higher enqueue order |
635 // and will be blocked from running. | 616 // and will be blocked from running. |
636 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence( | 617 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence( |
637 main_thread_only().current_fence); | 618 main_thread_only().current_fence); |
638 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence( | 619 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence( |
639 main_thread_only().current_fence); | 620 main_thread_only().current_fence); |
640 | 621 |
641 if (!task_unblocked && previous_fence && | 622 if (!task_unblocked && previous_fence && |
642 previous_fence < main_thread_only().current_fence) { | 623 previous_fence < main_thread_only().current_fence) { |
643 base::AutoLock lock(immediate_incoming_queue_lock_); | 624 base::AutoLock lock(immediate_incoming_queue_lock_); |
644 if (!immediate_incoming_queue().empty() && | 625 if (!immediate_incoming_queue().empty() && |
645 immediate_incoming_queue().front().enqueue_order() > previous_fence && | 626 immediate_incoming_queue().front().enqueue_order().sequence_num > |
646 immediate_incoming_queue().front().enqueue_order() < | 627 previous_fence && |
| 628 immediate_incoming_queue().front().enqueue_order().sequence_num < |
647 main_thread_only().current_fence) { | 629 main_thread_only().current_fence) { |
648 task_unblocked = true; | 630 task_unblocked = true; |
649 } | 631 } |
650 } | 632 } |
651 | 633 |
652 if (IsQueueEnabled() && task_unblocked) { | 634 if (IsQueueEnabled() && task_unblocked) { |
653 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( | 635 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( |
654 FROM_HERE); | 636 FROM_HERE); |
655 } | 637 } |
656 } | 638 } |
657 | 639 |
658 void TaskQueueImpl::RemoveFence() { | 640 void TaskQueueImpl::RemoveFence() { |
659 if (!main_thread_only().task_queue_manager) | 641 if (!main_thread_only().task_queue_manager) |
660 return; | 642 return; |
661 | 643 |
662 EnqueueOrder previous_fence = main_thread_only().current_fence; | 644 SequenceNumber previous_fence = main_thread_only().current_fence; |
663 main_thread_only().current_fence = 0; | 645 main_thread_only().current_fence = 0; |
664 | 646 |
665 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); | 647 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); |
666 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); | 648 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); |
667 | 649 |
668 if (!task_unblocked && previous_fence) { | 650 if (!task_unblocked && previous_fence) { |
669 base::AutoLock lock(immediate_incoming_queue_lock_); | 651 base::AutoLock lock(immediate_incoming_queue_lock_); |
670 if (!immediate_incoming_queue().empty() && | 652 if (!immediate_incoming_queue().empty() && |
671 immediate_incoming_queue().front().enqueue_order() > previous_fence) { | 653 immediate_incoming_queue().front().enqueue_order().sequence_num > |
| 654 previous_fence) { |
672 task_unblocked = true; | 655 task_unblocked = true; |
673 } | 656 } |
674 } | 657 } |
675 | 658 |
676 if (IsQueueEnabled() && task_unblocked) { | 659 if (IsQueueEnabled() && task_unblocked) { |
677 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( | 660 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( |
678 FROM_HERE); | 661 FROM_HERE); |
679 } | 662 } |
680 } | 663 } |
681 | 664 |
682 bool TaskQueueImpl::BlockedByFence() const { | 665 bool TaskQueueImpl::BlockedByFence() const { |
683 if (!main_thread_only().current_fence) | 666 if (!main_thread_only().current_fence) |
684 return false; | 667 return false; |
685 | 668 |
686 if (!main_thread_only().immediate_work_queue->BlockedByFence() || | 669 if (!main_thread_only().immediate_work_queue->BlockedByFence() || |
687 !main_thread_only().delayed_work_queue->BlockedByFence()) { | 670 !main_thread_only().delayed_work_queue->BlockedByFence()) { |
688 return false; | 671 return false; |
689 } | 672 } |
690 | 673 |
691 base::AutoLock lock(immediate_incoming_queue_lock_); | 674 base::AutoLock lock(immediate_incoming_queue_lock_); |
692 if (immediate_incoming_queue().empty()) | 675 if (immediate_incoming_queue().empty()) |
693 return true; | 676 return true; |
694 | 677 |
695 return immediate_incoming_queue().front().enqueue_order() > | 678 return immediate_incoming_queue().front().enqueue_order().sequence_num > |
696 main_thread_only().current_fence; | 679 main_thread_only().current_fence; |
697 } | 680 } |
698 | 681 |
699 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { | 682 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { |
700 if (!IsQueueEnabled()) | 683 if (!IsQueueEnabled()) |
701 return false; | 684 return false; |
702 | 685 |
703 if (!main_thread_only().current_fence) | 686 if (!main_thread_only().current_fence) |
704 return true; | 687 return true; |
705 | 688 |
706 return enqueue_order < main_thread_only().current_fence; | 689 return enqueue_order.sequence_num < main_thread_only().current_fence; |
707 } | 690 } |
708 | 691 |
709 EnqueueOrder TaskQueueImpl::GetFenceForTest() const { | 692 SequenceNumber TaskQueueImpl::GetFenceForTest() const { |
710 return main_thread_only().current_fence; | 693 return main_thread_only().current_fence; |
711 } | 694 } |
712 | 695 |
713 // static | 696 // static |
714 void TaskQueueImpl::QueueAsValueInto(const WTF::Deque<Task>& queue, | 697 void TaskQueueImpl::QueueAsValueInto(const WTF::Deque<Task>& queue, |
715 base::trace_event::TracedValue* state) { | 698 base::trace_event::TracedValue* state) { |
716 for (const Task& task : queue) { | 699 for (const Task& task : queue) { |
717 TaskAsValueInto(task, state); | 700 TaskAsValueInto(task, state); |
718 } | 701 } |
719 } | 702 } |
(...skipping 12 matching lines...) Expand all Loading... |
732 mutable_queue->pop(); | 715 mutable_queue->pop(); |
733 } | 716 } |
734 *mutable_queue = std::move(visited); | 717 *mutable_queue = std::move(visited); |
735 } | 718 } |
736 | 719 |
737 // static | 720 // static |
738 void TaskQueueImpl::TaskAsValueInto(const Task& task, | 721 void TaskQueueImpl::TaskAsValueInto(const Task& task, |
739 base::trace_event::TracedValue* state) { | 722 base::trace_event::TracedValue* state) { |
740 state->BeginDictionary(); | 723 state->BeginDictionary(); |
741 state->SetString("posted_from", task.posted_from.ToString()); | 724 state->SetString("posted_from", task.posted_from.ToString()); |
742 #ifndef NDEBUG | 725 state->SetInteger("enqueue_order.delayed_run_time", |
743 if (task.enqueue_order_set()) | 726 task.enqueue_order().delayed_run_time.ToInternalValue()); |
744 state->SetInteger("enqueue_order", task.enqueue_order()); | 727 state->SetInteger("enqueue_order.sequence_num", |
745 #else | 728 task.enqueue_order().sequence_num); |
746 state->SetInteger("enqueue_order", task.enqueue_order()); | |
747 #endif | |
748 state->SetInteger("sequence_num", task.sequence_num); | 729 state->SetInteger("sequence_num", task.sequence_num); |
749 state->SetBoolean("nestable", task.nestable); | 730 state->SetBoolean("nestable", task.nestable); |
750 state->SetBoolean("is_high_res", task.is_high_res); | 731 state->SetBoolean("is_high_res", task.is_high_res); |
751 state->SetBoolean("is_cancelled", task.task.IsCancelled()); | 732 state->SetBoolean("is_cancelled", task.task.IsCancelled()); |
752 state->SetDouble( | 733 state->SetDouble( |
753 "delayed_run_time", | 734 "delayed_run_time", |
754 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 735 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
755 state->EndDictionary(); | 736 state->EndDictionary(); |
756 } | 737 } |
757 | 738 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 } | 884 } |
904 | 885 |
905 void TaskQueueImpl::NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up) { | 886 void TaskQueueImpl::NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up) { |
906 if (main_thread_only().observer) | 887 if (main_thread_only().observer) |
907 main_thread_only().observer->OnQueueNextWakeUpChanged(this, wake_up); | 888 main_thread_only().observer->OnQueueNextWakeUpChanged(this, wake_up); |
908 } | 889 } |
909 | 890 |
910 } // namespace internal | 891 } // namespace internal |
911 } // namespace scheduler | 892 } // namespace scheduler |
912 } // namespace blink | 893 } // namespace blink |
OLD | NEW |