// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_MANAGER_IMPL_H_ #define CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_MANAGER_IMPL_H_ #include #include #include #include #include #include #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" #include "base/time/time.h" #include "chrome/browser/task_manager/providers/task_provider.h" #include "chrome/browser/task_manager/providers/task_provider_observer.h" #include "chrome/browser/task_manager/sampling/task_group.h" #include "chrome/browser/task_manager/task_manager_interface.h" #include "gpu/ipc/common/memory_stats.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" #if defined(OS_CHROMEOS) #include "chrome/browser/task_manager/sampling/arc_shared_sampler.h" #endif // defined(OS_CHROMEOS) namespace task_manager { class SharedSampler; // Identifies the initiator of a network request, by a (child_id, // route_id) tuple. // BytesTransferredKey supports hashing and may be used as an unordered_map key. struct BytesTransferredKey { // The unique ID of the host of the child process requester. int child_id; // The ID of the IPC route for the URLRequest (this identifies the // RenderView or like-thing in the renderer that the request gets routed // to). int route_id; struct Hasher { size_t operator()(const BytesTransferredKey& key) const; }; bool operator==(const BytesTransferredKey& other) const; }; // This is the entry of the unordered map that tracks bytes transfered by task. struct BytesTransferredParam { // The number of bytes read. int64_t byte_read_count = 0; // The number of bytes sent. int64_t byte_sent_count = 0; }; using BytesTransferredMap = std::unordered_map; // Defines a concrete implementation of the TaskManagerInterface. class TaskManagerImpl : public TaskManagerInterface, public TaskProviderObserver { public: ~TaskManagerImpl() override; static TaskManagerImpl* GetInstance(); // task_manager::TaskManagerInterface: void ActivateTask(TaskId task_id) override; bool IsTaskKillable(TaskId task_id) override; void KillTask(TaskId task_id) override; double GetPlatformIndependentCPUUsage(TaskId task_id) const override; base::Time GetStartTime(TaskId task_id) const override; base::TimeDelta GetCpuTime(TaskId task_id) const override; int64_t GetMemoryFootprintUsage(TaskId task_id) const override; int64_t GetSwappedMemoryUsage(TaskId task_id) const override; int64_t GetGpuMemoryUsage(TaskId task_id, bool* has_duplicates) const override; int GetIdleWakeupsPerSecond(TaskId task_id) const override; int GetHardFaultsPerSecond(TaskId task_id) const override; int GetNaClDebugStubPort(TaskId task_id) const override; void GetGDIHandles(TaskId task_id, int64_t* current, int64_t* peak) const override; void GetUSERHandles(TaskId task_id, int64_t* current, int64_t* peak) const override; int GetOpenFdCount(TaskId task_id) const override; bool IsTaskOnBackgroundedProcess(TaskId task_id) const override; const base::string16& GetTitle(TaskId task_id) const override; base::string16 GetProfileName(TaskId task_id) const override; const gfx::ImageSkia& GetIcon(TaskId task_id) const override; const base::ProcessHandle& GetProcessHandle(TaskId task_id) const override; const base::ProcessId& GetProcessId(TaskId task_id) const override; Task::Type GetType(TaskId task_id) const override; SessionID GetTabId(TaskId task_id) const override; int GetChildProcessUniqueId(TaskId task_id) const override; void GetTerminationStatus(TaskId task_id, base::TerminationStatus* out_status, int* out_error_code) const override; int64_t GetNetworkUsage(TaskId task_id) const override; int64_t GetCumulativeNetworkUsage(TaskId task_id) const override; int64_t GetProcessTotalNetworkUsage(TaskId task_id) const override; int64_t GetCumulativeProcessTotalNetworkUsage(TaskId task_id) const override; int64_t GetSqliteMemoryUsed(TaskId task_id) const override; bool GetV8Memory(TaskId task_id, int64_t* allocated, int64_t* used) const override; bool GetWebCacheStats(TaskId task_id, blink::WebCacheResourceTypeStats* stats) const override; int GetKeepaliveCount(TaskId task_id) const override; const TaskIdList& GetTaskIdsList() const override; TaskIdList GetIdsOfTasksSharingSameProcess(TaskId task_id) const override; size_t GetNumberOfTasksOnSameProcess(TaskId task_id) const override; bool IsRunningInVM(TaskId task_id) const override; TaskId GetTaskIdForWebContents( content::WebContents* web_contents) const override; // task_manager::TaskProviderObserver: void TaskAdded(Task* task) override; void TaskRemoved(Task* task) override; void TaskUnresponsive(Task* task) override; // Used when Network Service is enabled. // Receives total network usages from |NetworkService|. void OnTotalNetworkUsages( std::vector total_network_usages); private: using PidToTaskGroupMap = std::map>; friend struct base::LazyInstanceTraitsBase; TaskManagerImpl(); void OnVideoMemoryUsageStatsUpdate( const gpu::VideoMemoryUsageStats& gpu_memory_stats); void OnReceivedMemoryDump( bool success, std::unique_ptr dump); // task_manager::TaskManagerInterface: void Refresh() override; void StartUpdating() override; void StopUpdating() override; // Lookup a task by child_id and possibly route_id. Task* GetTaskByRoute(int child_id, int route_id) const; // Based on |param| the appropriate task will be updated by its network usage. // Returns true if it was able to match |param| to an existing task, returns // false otherwise, at which point the caller must explicitly match these // bytes to the browser process by calling this method again with // |param.origin_pid = 0| and |param.child_id = param.route_id = -1|. bool UpdateTasksWithBytesTransferred(const BytesTransferredKey& key, const BytesTransferredParam& param); PidToTaskGroupMap* GetVmPidToTaskGroupMap(Task::Type type); TaskGroup* GetTaskGroupByTaskId(TaskId task_id) const; Task* GetTaskByTaskId(TaskId task_id) const; // Called back by a TaskGroup when the resource calculations done on the // background thread has completed. void OnTaskGroupBackgroundCalculationsDone(); const base::RepeatingClosure on_background_data_ready_callback_; // Map TaskGroups by the IDs of the processes they represent. PidToTaskGroupMap task_groups_by_proc_id_; // Map ARC VM PidToTaskGroupMaps by the task type. This should be separate // from the non-VM map |task_groups_by_proc_id_| as there can be conflicting // PIDs. PidToTaskGroupMap arc_vm_task_groups_by_proc_id_; // Map each task by its ID to the TaskGroup on which it resides. // Keys are unique but values will have duplicates (i.e. multiple tasks // running on the same process represented by a single TaskGroup). std::map task_groups_by_task_id_; // A cached sorted list of the task IDs. mutable std::vector sorted_task_ids_; // Used when Network Service is enabled. // Stores the total network usages per |process_id, routing_id| from last // refresh. BytesTransferredMap last_refresh_total_network_usages_map_; // The list of the task providers that are owned and observed by this task // manager implementation. std::vector> task_providers_; // The current GPU memory usage stats that was last received from the // GpuDataManager. gpu::VideoMemoryUsageStats gpu_memory_stats_; // The specific blocking pool SequencedTaskRunner that will be used to make // sure TaskGroupSampler posts their refreshes serially. scoped_refptr blocking_pool_runner_; // A special sampler shared with all instances of TaskGroup that calculates a // subset of resources for all processes at once. scoped_refptr shared_sampler_; #if defined(OS_CHROMEOS) // A sampler shared with all instances of TaskGroup that hold ARC tasks and // calculates memory footprint for all processes at once. std::unique_ptr arc_shared_sampler_; #endif // defined(OS_CHROMEOS) // This will be set to true while there are observers and the task manager is // running. bool is_running_; // This is set to true while waiting for a global memory dump from // memory_instrumentation. bool waiting_for_memory_dump_; base::WeakPtrFactory weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(TaskManagerImpl); }; } // namespace task_manager #endif // CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_MANAGER_IMPL_H_