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