Commit 6b44cb09 authored by Harkiran Bolaria's avatar Harkiran Bolaria Committed by Commit Bot

[bfcache] Add tracking for IPC tasks posted to cached pages

Add callback to handle specialized behavior when tasks are posted. To be filled with IPC tracking for cached frames in a subsequent Cl.

Bug: 1110344
Change-Id: I7a053747082782a0c2f6c44a7b77aeb6f9694d96
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2316781
Commit-Queue: Harkiran Bolaria <hbolaria@google.com>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799855}
parent 876f0b19
...@@ -3479,6 +3479,8 @@ void SetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue, ...@@ -3479,6 +3479,8 @@ void SetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue,
[](int* counter, const Task& task, TaskQueue::TaskTiming* task_timing, [](int* counter, const Task& task, TaskQueue::TaskTiming* task_timing,
LazyNow* lazy_now) { ++(*counter); }, LazyNow* lazy_now) { ++(*counter); },
complete_counter)); complete_counter));
task_queue->GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
} }
void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) { void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) {
...@@ -3486,6 +3488,8 @@ void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) { ...@@ -3486,6 +3488,8 @@ void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) {
internal::TaskQueueImpl::OnTaskStartedHandler()); internal::TaskQueueImpl::OnTaskStartedHandler());
task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler( task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(
internal::TaskQueueImpl::OnTaskCompletedHandler()); internal::TaskQueueImpl::OnTaskCompletedHandler());
task_queue->GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
} }
} // namespace } // namespace
......
...@@ -183,6 +183,7 @@ void TaskQueue::ShutdownTaskQueue() { ...@@ -183,6 +183,7 @@ void TaskQueue::ShutdownTaskQueue() {
internal::TaskQueueImpl::OnTaskStartedHandler()); internal::TaskQueueImpl::OnTaskStartedHandler());
impl_->SetOnTaskCompletedHandler( impl_->SetOnTaskCompletedHandler(
internal::TaskQueueImpl::OnTaskCompletedHandler()); internal::TaskQueueImpl::OnTaskCompletedHandler());
impl_->SetOnTaskPostedHandler(internal::TaskQueueImpl::OnTaskPostedHandler());
sequence_manager_->UnregisterTaskQueueImpl(TakeTaskQueueImpl()); sequence_manager_->UnregisterTaskQueueImpl(TakeTaskQueueImpl());
} }
......
...@@ -306,6 +306,10 @@ void TaskQueueImpl::PostImmediateTaskImpl(PostedTask task, ...@@ -306,6 +306,10 @@ void TaskQueueImpl::PostImmediateTaskImpl(PostedTask task,
&any_thread_.immediate_incoming_queue.back(), name_); &any_thread_.immediate_incoming_queue.back(), name_);
MaybeReportIpcTaskQueuedFromAnyThreadLocked( MaybeReportIpcTaskQueuedFromAnyThreadLocked(
&any_thread_.immediate_incoming_queue.back(), name_); &any_thread_.immediate_incoming_queue.back(), name_);
if (!any_thread_.on_task_posted_handler.is_null()) {
any_thread_.on_task_posted_handler.Run(
any_thread_.immediate_incoming_queue.back());
}
// If this queue was completely empty, then the SequenceManager needs to be // If this queue was completely empty, then the SequenceManager needs to be
// informed so it can reload the work queue and add us to the // informed so it can reload the work queue and add us to the
...@@ -1177,6 +1181,12 @@ bool TaskQueueImpl::RequiresTaskTiming() const { ...@@ -1177,6 +1181,12 @@ bool TaskQueueImpl::RequiresTaskTiming() const {
!main_thread_only().on_task_completed_handler.is_null(); !main_thread_only().on_task_completed_handler.is_null();
} }
void TaskQueueImpl::SetOnTaskPostedHandler(OnTaskPostedHandler handler) {
DCHECK(should_notify_observers_ || handler.is_null());
base::internal::CheckedAutoLock lock(any_thread_lock_);
any_thread_.on_task_posted_handler = std::move(handler);
}
bool TaskQueueImpl::IsUnregistered() const { bool TaskQueueImpl::IsUnregistered() const {
base::internal::CheckedAutoLock lock(any_thread_lock_); base::internal::CheckedAutoLock lock(any_thread_lock_);
return any_thread_.unregistered; return any_thread_.unregistered;
......
...@@ -95,6 +95,7 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -95,6 +95,7 @@ class BASE_EXPORT TaskQueueImpl {
RepeatingCallback<void(const Task&, const TaskQueue::TaskTiming&)>; RepeatingCallback<void(const Task&, const TaskQueue::TaskTiming&)>;
using OnTaskCompletedHandler = using OnTaskCompletedHandler =
RepeatingCallback<void(const Task&, TaskQueue::TaskTiming*, LazyNow*)>; RepeatingCallback<void(const Task&, TaskQueue::TaskTiming*, LazyNow*)>;
using OnTaskPostedHandler = RepeatingCallback<void(const Task&)>;
// May be called from any thread. // May be called from any thread.
scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner( scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner(
...@@ -217,6 +218,13 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -217,6 +218,13 @@ class BASE_EXPORT TaskQueueImpl {
LazyNow* lazy_now); LazyNow* lazy_now);
bool RequiresTaskTiming() const; bool RequiresTaskTiming() const;
// Set a callback for adding custom functionality for processing posted task.
// Callback will be dispatched while holding a scheduler lock. As a result,
// callback should not call scheduler APIs directly, as this can lead to
// deadlocks. For example, PostTask should not be called directly and
// ScopedDeferTaskPosting::PostOrDefer should be used instead.
void SetOnTaskPostedHandler(OnTaskPostedHandler handler);
WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr(); WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr();
SequenceManagerImpl* sequence_manager() const { return sequence_manager_; } SequenceManagerImpl* sequence_manager() const { return sequence_manager_; }
...@@ -497,6 +505,8 @@ class BASE_EXPORT TaskQueueImpl { ...@@ -497,6 +505,8 @@ class BASE_EXPORT TaskQueueImpl {
bool unregistered = false; bool unregistered = false;
OnTaskPostedHandler on_task_posted_handler;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// A cache of |immediate_work_queue->work_queue_set_index()| which is used // A cache of |immediate_work_queue->work_queue_set_index()| which is used
// to index into // to index into
......
...@@ -36,6 +36,7 @@ include_rules = [ ...@@ -36,6 +36,7 @@ include_rules = [
"+base/synchronization/atomic_flag.h", "+base/synchronization/atomic_flag.h",
"+base/synchronization/cancellation_flag.h", "+base/synchronization/cancellation_flag.h",
"+base/synchronization/lock.h", "+base/synchronization/lock.h",
"+base/task/common/scoped_defer_task_posting.h",
"+base/task/sequence_manager/lazy_now.h", "+base/task/sequence_manager/lazy_now.h",
"+base/task/sequence_manager/sequence_manager.h", "+base/task/sequence_manager/sequence_manager.h",
"+base/task/sequence_manager/task_queue.h", "+base/task/sequence_manager/task_queue.h",
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/task/common/scoped_defer_task_posting.h"
#include "base/task/sequence_manager/lazy_now.h" #include "base/task/sequence_manager/lazy_now.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/trace_event/blame_context.h" #include "base/trace_event/blame_context.h"
...@@ -715,6 +716,11 @@ void FrameSchedulerImpl::ReportActiveSchedulerTrackedFeatures() { ...@@ -715,6 +716,11 @@ void FrameSchedulerImpl::ReportActiveSchedulerTrackedFeatures() {
ReportFeaturesToDelegate(); ReportFeaturesToDelegate();
} }
base::WeakPtr<FrameSchedulerImpl>
FrameSchedulerImpl::GetInvalidingOnBFCacheRestoreWeakPtr() {
return invalidating_on_bfcache_restore_weak_factory_.GetWeakPtr();
}
void FrameSchedulerImpl::OnAddedAllThrottlingOptOut() { void FrameSchedulerImpl::OnAddedAllThrottlingOptOut() {
++all_throttling_opt_out_count_; ++all_throttling_opt_out_count_;
opted_out_from_all_throttling_ = opted_out_from_all_throttling_ =
...@@ -1209,6 +1215,48 @@ void FrameSchedulerImpl::OnTaskQueueCreated( ...@@ -1209,6 +1215,48 @@ void FrameSchedulerImpl::OnTaskQueueCreated(
} }
} }
void FrameSchedulerImpl::SetOnIPCTaskPostedWhileInBackForwardCacheHandler() {
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
task_queue_and_voter.first->SetOnIPCTaskPosted(base::BindRepeating(
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<FrameSchedulerImpl> frame_scheduler,
const base::sequence_manager::Task& task) {
// Only log IPC tasks. IPC tasks are only logged currently as IPC
// hash can be mapped back to a function name, and IPC tasks may
// potentially post sensitive information.
if (!task.ipc_hash) {
return;
}
base::ScopedDeferTaskPosting::PostOrDefer(
task_runner, FROM_HERE,
base::BindOnce(
&FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache,
frame_scheduler, task.ipc_hash, task.posted_from),
base::TimeDelta());
},
main_thread_scheduler_->DefaultTaskRunner(),
GetInvalidingOnBFCacheRestoreWeakPtr()));
}
}
void FrameSchedulerImpl::DetachOnIPCTaskPostedWhileInBackForwardCacheHandler() {
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
task_queue_and_voter.first->DetachOnIPCTaskPostedWhileInBackForwardCache();
}
invalidating_on_bfcache_restore_weak_factory_.InvalidateWeakPtrs();
}
void FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache(
uint32_t ipc_hash,
const base::Location& task_from) {
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
// TODO - start recording metrics
}
WTF::HashSet<SchedulingPolicy::Feature> WTF::HashSet<SchedulingPolicy::Feature>
FrameSchedulerImpl::GetActiveFeaturesTrackedForBackForwardCacheMetrics() { FrameSchedulerImpl::GetActiveFeaturesTrackedForBackForwardCacheMetrics() {
WTF::HashSet<SchedulingPolicy::Feature> result; WTF::HashSet<SchedulingPolicy::Feature> result;
......
...@@ -142,6 +142,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, ...@@ -142,6 +142,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
base::WeakPtr<FrameScheduler> GetWeakPtr() override; base::WeakPtr<FrameScheduler> GetWeakPtr() override;
base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const; base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
base::WeakPtr<FrameSchedulerImpl> GetInvalidingOnBFCacheRestoreWeakPtr();
void ReportActiveSchedulerTrackedFeatures() override; void ReportActiveSchedulerTrackedFeatures() override;
...@@ -180,6 +181,11 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, ...@@ -180,6 +181,11 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
MainThreadTaskQueue*, MainThreadTaskQueue*,
base::sequence_manager::TaskQueue::QueueEnabledVoter*) override; base::sequence_manager::TaskQueue::QueueEnabledVoter*) override;
void SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
void DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
void OnIPCTaskPostedWhileInBackForwardCache(uint32_t ipc_hash,
const base::Location& task_from);
// Returns the list of active features which currently tracked by the // Returns the list of active features which currently tracked by the
// scheduler for back-forward cache metrics. // scheduler for back-forward cache metrics.
WTF::HashSet<SchedulingPolicy::Feature> WTF::HashSet<SchedulingPolicy::Feature>
...@@ -382,6 +388,12 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler, ...@@ -382,6 +388,12 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// and documents. // and documents.
base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this}; base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this};
// WeakPtrFactory for tracking IPCs posted to frames cached in the
// back-forward cache. These weak pointers are invalidated when the page is
// restored from the cache.
base::WeakPtrFactory<FrameSchedulerImpl>
invalidating_on_bfcache_restore_weak_factory_{this};
mutable base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_{this}; mutable base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl); DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/task/common/scoped_defer_task_posting.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h" #include "third_party/blink/renderer/platform/wtf/wtf.h"
...@@ -191,11 +192,30 @@ void MainThreadTaskQueue::DetachFromMainThreadScheduler() { ...@@ -191,11 +192,30 @@ void MainThreadTaskQueue::DetachFromMainThreadScheduler() {
GetTaskQueueImpl()->SetOnTaskCompletedHandler( GetTaskQueueImpl()->SetOnTaskCompletedHandler(
base::BindRepeating(&MainThreadSchedulerImpl::OnTaskCompleted, base::BindRepeating(&MainThreadSchedulerImpl::OnTaskCompleted,
main_thread_scheduler_->GetWeakPtr(), nullptr)); main_thread_scheduler_->GetWeakPtr(), nullptr));
GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
} }
ClearReferencesToSchedulers(); ClearReferencesToSchedulers();
} }
void MainThreadTaskQueue::SetOnIPCTaskPosted(
base::RepeatingCallback<void(const base::sequence_manager::Task&)>
on_ipc_task_posted_callback) {
if (GetTaskQueueImpl()) {
// We use the frame_scheduler_ to track metrics so as to ensure that metrics
// are not tied to individual task queues.
GetTaskQueueImpl()->SetOnTaskPostedHandler(on_ipc_task_posted_callback);
}
}
void MainThreadTaskQueue::DetachOnIPCTaskPostedWhileInBackForwardCache() {
if (GetTaskQueueImpl()) {
GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
}
}
void MainThreadTaskQueue::ShutdownTaskQueue() { void MainThreadTaskQueue::ShutdownTaskQueue() {
ClearReferencesToSchedulers(); ClearReferencesToSchedulers();
TaskQueue::ShutdownTaskQueue(); TaskQueue::ShutdownTaskQueue();
......
...@@ -383,6 +383,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue ...@@ -383,6 +383,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue
base::sequence_manager::TaskQueue::TaskTiming* task_timing, base::sequence_manager::TaskQueue::TaskTiming* task_timing,
base::sequence_manager::LazyNow* lazy_now); base::sequence_manager::LazyNow* lazy_now);
void SetOnIPCTaskPosted(
base::RepeatingCallback<void(const base::sequence_manager::Task&)>
on_ipc_task_posted_callback);
void DetachOnIPCTaskPostedWhileInBackForwardCache();
void DetachFromMainThreadScheduler(); void DetachFromMainThreadScheduler();
// Override base method to notify MainThreadScheduler about shutdown queue. // Override base method to notify MainThreadScheduler about shutdown queue.
......
...@@ -323,6 +323,28 @@ void PageSchedulerImpl::SetPageFrozenImpl( ...@@ -323,6 +323,28 @@ void PageSchedulerImpl::SetPageFrozenImpl(
void PageSchedulerImpl::SetPageBackForwardCached( void PageSchedulerImpl::SetPageBackForwardCached(
bool is_in_back_forward_cache) { bool is_in_back_forward_cache) {
is_stored_in_back_forward_cache_ = is_in_back_forward_cache; is_stored_in_back_forward_cache_ = is_in_back_forward_cache;
if (!is_stored_in_back_forward_cache_) {
set_ipc_posted_handler_task_.Cancel();
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
frame_scheduler->DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
}
} else {
// Incorporate a delay of 15 seconds to allow for caching operations to
// complete before tasks are logged.
set_ipc_posted_handler_task_ = PostDelayedCancellableTask(
*main_thread_scheduler_->ControlTaskRunner(), FROM_HERE,
base::BindRepeating(&PageSchedulerImpl::SetUpIPCTaskDetection,
GetWeakPtr()),
base::TimeDelta::FromSeconds(15));
}
}
void PageSchedulerImpl::SetUpIPCTaskDetection() {
DCHECK(is_stored_in_back_forward_cache_);
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
frame_scheduler->SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
}
} }
void PageSchedulerImpl::SetKeepActive(bool keep_active) { void PageSchedulerImpl::SetKeepActive(bool keep_active) {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h" #include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h"
...@@ -62,6 +63,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { ...@@ -62,6 +63,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void SetPageVisible(bool page_visible) override; void SetPageVisible(bool page_visible) override;
void SetPageFrozen(bool) override; void SetPageFrozen(bool) override;
void SetPageBackForwardCached(bool) override; void SetPageBackForwardCached(bool) override;
bool IsStoredInBackForwardCache() { return is_stored_in_back_forward_cache_; }
void SetKeepActive(bool) override; void SetKeepActive(bool) override;
bool IsMainFrameLocal() const override; bool IsMainFrameLocal() const override;
void SetIsMainFrameLocal(bool is_local) override; void SetIsMainFrameLocal(bool is_local) override;
...@@ -128,7 +130,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { ...@@ -128,7 +130,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
PageLifecycleState GetPageLifecycleState() const; PageLifecycleState GetPageLifecycleState() const;
// Generally UKMs are asssociated with the main frame of a page, but the void SetUpIPCTaskDetection();
// Generally UKMs are associated with the main frame of a page, but the
// implementation allows to request a recorder from any local frame with // implementation allows to request a recorder from any local frame with
// the same result (e.g. for OOPIF support), therefore we need to select // the same result (e.g. for OOPIF support), therefore we need to select
// any frame here. // any frame here.
...@@ -327,6 +331,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { ...@@ -327,6 +331,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
const base::TimeDelta delay_for_background_and_network_idle_tab_freezing_; const base::TimeDelta delay_for_background_and_network_idle_tab_freezing_;
bool is_stored_in_back_forward_cache_ = false; bool is_stored_in_back_forward_cache_ = false;
TaskHandle set_ipc_posted_handler_task_;
std::unique_ptr<PageLifecycleStateTracker> page_lifecycle_state_tracker_; std::unique_ptr<PageLifecycleStateTracker> page_lifecycle_state_tracker_;
base::WeakPtrFactory<PageSchedulerImpl> weak_factory_{this}; base::WeakPtrFactory<PageSchedulerImpl> weak_factory_{this};
......
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