diff options
-rw-r--r-- | base/process_util.h | 10 | ||||
-rw-r--r-- | base/process_util_linux.cc | 15 | ||||
-rw-r--r-- | base/process_util_mac.mm | 12 | ||||
-rw-r--r-- | base/process_util_win.cc | 23 | ||||
-rw-r--r-- | chrome/browser/task_manager.cc | 56 | ||||
-rw-r--r-- | chrome/browser/task_manager.h | 19 |
6 files changed, 102 insertions, 33 deletions
diff --git a/base/process_util.h b/base/process_util.h index ec3510a..b8bcfd4 100644 --- a/base/process_util.h +++ b/base/process_util.h @@ -481,10 +481,12 @@ class ProcessMetrics { size_t GetWorkingSetSize() const; // Returns the peak working set size, in bytes. size_t GetPeakWorkingSetSize() const; - // Returns private usage, in bytes. Private bytes is the amount - // of memory currently allocated to a process that cannot be shared. - // Note: returns 0 on unsupported OSes: prior to XP SP2. - size_t GetPrivateBytes() const; + // Returns private and sharedusage, in bytes. Private bytes is the amount of + // memory currently allocated to a process that cannot be shared. Returns + // false on platform specific error conditions. Note: |private_bytes| + // returns 0 on unsupported OSes: prior to XP SP2. + bool GetMemoryBytes(size_t* private_bytes, + size_t* shared_bytes); // Fills a CommittedKBytes with both resident and paged // memory usage as per definition of CommittedBytes. void GetCommittedKBytes(CommittedKBytes* usage) const; diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc index 0a2cc0d..ee44638 100644 --- a/base/process_util_linux.cc +++ b/base/process_util_linux.cc @@ -244,10 +244,19 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const { return 0; } -size_t ProcessMetrics::GetPrivateBytes() const { +bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, + size_t* shared_bytes) { WorkingSetKBytes ws_usage; - GetWorkingSetKBytes(&ws_usage); - return ws_usage.priv << 10; + if (!GetWorkingSetKBytes(&ws_usage)) + return false; + + if (private_bytes) + *private_bytes = ws_usage.priv << 10; + + if (shared_bytes) + *shared_bytes = ws_usage.shared * 1024; + + return true; } // Private and Shared working set sizes are obtained from /proc/<pid>/smaps. diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm index f119e78..9fcc43c 100644 --- a/base/process_util_mac.mm +++ b/base/process_util_mac.mm @@ -222,10 +222,16 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const { return 0; } -size_t ProcessMetrics::GetPrivateBytes() const { - return 0; +// OSX appears to use a different system to get its memory. +bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, + size_t* shared_bytes) { + if (private_bytes) + *private_bytes = 0; + if (shared_bytes) + *shared_bytes = 0; + return true; } - + void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { } diff --git a/base/process_util_win.cc b/base/process_util_win.cc index 8df8de5..2eb73ca 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -515,18 +515,29 @@ size_t ProcessMetrics::GetPeakWorkingSetSize() const { return 0; } -size_t ProcessMetrics::GetPrivateBytes() const { +bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes, + size_t* shared_bytes) { // PROCESS_MEMORY_COUNTERS_EX is not supported until XP SP2. // GetProcessMemoryInfo() will simply fail on prior OS. So the requested // information is simply not available. Hence, we will return 0 on unsupported // OSes. Unlike most Win32 API, we don't need to initialize the "cb" member. PROCESS_MEMORY_COUNTERS_EX pmcx; - if (GetProcessMemoryInfo(process_, - reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx), - sizeof(pmcx))) { - return pmcx.PrivateUsage; + if (private_bytes && + GetProcessMemoryInfo(process_, + reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx), + sizeof(pmcx))) { + *private_bytes = pmcx.PrivateUsage; } - return 0; + + if (shared_bytes) { + WorkingSetKBytes ws_usage; + if (!GetWorkingSetKBytes(&ws_usage)) + return false; + + *shared_bytes = ws_usage.shared * 1024; + } + + return true; } void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc index a604b70..1d2907a 100644 --- a/chrome/browser/task_manager.cc +++ b/chrome/browser/task_manager.cc @@ -404,25 +404,34 @@ double TaskManagerModel::GetCPUUsage(TaskManager::Resource* resource) const { } bool TaskManagerModel::GetPrivateMemory(int index, size_t* result) const { - *result = 0; - base::ProcessMetrics* process_metrics; - if (!GetProcessMetricsForRow(index, &process_metrics)) - return false; - *result = process_metrics->GetPrivateBytes(); - if (*result == 0) - return false; + base::ProcessHandle handle = resources_[index]->GetProcess(); + MemoryUsageMap::const_iterator iter = memory_usage_map_.find(handle); + if (iter == memory_usage_map_.end()) { + std::pair<size_t, size_t> usage; + if (!GetAndCacheMemoryMetrics(handle, &usage)) + return false; + + *result = usage.first; + } else { + *result = iter->second.first; + } + return true; } bool TaskManagerModel::GetSharedMemory(int index, size_t* result) const { - *result = 0; - base::ProcessMetrics* process_metrics; - if (!GetProcessMetricsForRow(index, &process_metrics)) - return false; - base::WorkingSetKBytes ws_usage; - if (!process_metrics->GetWorkingSetKBytes(&ws_usage)) - return false; - *result = ws_usage.shared * 1024; + base::ProcessHandle handle = resources_[index]->GetProcess(); + MemoryUsageMap::const_iterator iter = memory_usage_map_.find(handle); + if (iter == memory_usage_map_.end()) { + std::pair<size_t, size_t> usage; + if (!GetAndCacheMemoryMetrics(handle, &usage)) + return false; + + *result = usage.second; + } else { + *result = iter->second.second; + } + return true; } @@ -718,6 +727,9 @@ void TaskManagerModel::Refresh() { cpu_usage_map_[process] = metrics_iter->second->GetCPUUsage(); } + // Clear the memory values so they can be querried lazily. + memory_usage_map_.clear(); + // Compute the new network usage values. displayed_network_usage_map_.clear(); for (ResourceValueMap::iterator iter = current_byte_count_map_.begin(); @@ -952,3 +964,17 @@ void TaskManager::OpenAboutMemory() { browser->window()->Show(); } } + +bool TaskManagerModel::GetAndCacheMemoryMetrics( + base::ProcessHandle handle, + std::pair<size_t, size_t>* usage) const { + MetricsMap::const_iterator iter = metrics_map_.find(handle); + if (iter == metrics_map_.end()) + return false; + + if (!iter->second->GetMemoryBytes(&usage->first, &usage->second)) + return false; + + memory_usage_map_.insert(std::make_pair(handle, *usage)); + return true; +} diff --git a/chrome/browser/task_manager.h b/chrome/browser/task_manager.h index 88b452d..6f807b8 100644 --- a/chrome/browser/task_manager.h +++ b/chrome/browser/task_manager.h @@ -300,6 +300,8 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap; typedef std::map<base::ProcessHandle, double> CPUUsageMap; typedef std::map<TaskManager::Resource*, int64> ResourceValueMap; + typedef std::map<base::ProcessHandle, + std::pair<size_t, size_t> > MemoryUsageMap; // Updates the values for all rows. void Refresh(); @@ -328,11 +330,13 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, double GetCPUUsage(TaskManager::Resource* resource) const; // Gets the private memory (in bytes) that should be displayed for the passed - // resource index. + // resource index. Caches the result since this calculation can take time on + // some platforms. bool GetPrivateMemory(int index, size_t* result) const; // Gets the shared memory (in bytes) that should be displayed for the passed - // resource index. + // resource index. Caches the result since this calculation can take time on + // some platforms. bool GetSharedMemory(int index, size_t* result) const; // Gets the physical memory (in bytes) that should be displayed for the passed @@ -355,6 +359,11 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, // displayed in the task manager's memory cell. std::wstring GetMemCellText(int64 number) const; + // Looks up the data for |handle| and puts it in the mutable cache + // |memory_usage_map_|. + bool GetAndCacheMemoryMetrics(base::ProcessHandle handle, + std::pair<size_t, size_t>* usage) const; + // The list of providers to the task manager. They are ref counted. ResourceProviderList providers_; @@ -383,6 +392,12 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver, // A map that contains the CPU usage (in %) for a process since last refresh. CPUUsageMap cpu_usage_map_; + // A map that contains the private/shared memory usage of the process. We + // cache this because the same APIs are called on linux and windows, and + // because the linux call takes >10ms to complete. This cache is cleared on + // every Refresh(). + mutable MemoryUsageMap memory_usage_map_; + ObserverList<TaskManagerModelObserver> observer_list_; // Whether we are currently in the process of updating. |