| Index: chrome/browser/private_working_set_snapshot_win.cc
|
| diff --git a/chrome/browser/private_working_set_snapshot_win.cc b/chrome/browser/private_working_set_snapshot_win.cc
|
| deleted file mode 100644
|
| index 56fb568e7ff640dddaac6ca510b5f80cca26e282..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/private_working_set_snapshot_win.cc
|
| +++ /dev/null
|
| @@ -1,160 +0,0 @@
|
| -// 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.
|
| -
|
| -#include "chrome/browser/private_working_set_snapshot.h"
|
| -
|
| -#include <pdh.h>
|
| -#include <pdhmsg.h>
|
| -
|
| -#include <algorithm>
|
| -
|
| -#include "base/numerics/safe_conversions.h"
|
| -#include "base/win/windows_version.h"
|
| -
|
| -// Link pdh.lib (import library for pdh.dll) whenever this file is linked in.
|
| -#pragma comment(lib, "pdh.lib")
|
| -
|
| -PrivateWorkingSetSnapshot::PrivateWorkingSetSnapshot() {
|
| - // The Pdh APIs are supported on Windows XP, but the "Working Set - Private"
|
| - // counter that PrivateWorkingSetSnapshot depends on is not defined until
|
| - // Windows Vista. Early-out to avoid wasted effort. All queries will return
|
| - // zero and will have to use the fallback calculations.
|
| - if (base::win::GetVersion() < base::win::VERSION_VISTA)
|
| - return;
|
| -
|
| - // Create a Pdh query
|
| - PDH_HQUERY query_handle;
|
| - if (PdhOpenQuery(NULL, NULL, &query_handle) != ERROR_SUCCESS) {
|
| - return;
|
| - }
|
| -
|
| - query_handle_.Set(query_handle);
|
| -}
|
| -
|
| -PrivateWorkingSetSnapshot::~PrivateWorkingSetSnapshot() {
|
| -}
|
| -
|
| -void PrivateWorkingSetSnapshot::AddToMonitorList(
|
| - const std::string& process_name) {
|
| - if (!query_handle_.IsValid())
|
| - return;
|
| -
|
| - // Create the magic strings that will return a list of process IDs and a list
|
| - // of private working sets. The 'process_name' variable should be something
|
| - // like "chrome". The '*' character indicates that we want records for all
|
| - // processes whose names start with process_name - all chrome processes, but
|
| - // also all 'chrome_editor.exe' processes or other matching names. The excess
|
| - // information is unavoidable but harmless.
|
| - std::string process_id_query = "\\Process(" + process_name + "*)\\ID Process";
|
| - std::string private_ws_query =
|
| - "\\Process(" + process_name + "*)\\Working Set - Private";
|
| -
|
| - // Add the two counters to the query.
|
| - PdhCounterPair new_counters;
|
| - if (PdhAddCounterA(query_handle_.Get(), process_id_query.c_str(), NULL,
|
| - &new_counters.process_id_handle) != ERROR_SUCCESS) {
|
| - return;
|
| - }
|
| -
|
| - // If adding the second counter fails then we should remove the first one.
|
| - if (PdhAddCounterA(query_handle_.Get(), private_ws_query.c_str(), NULL,
|
| - &new_counters.private_ws_handle) != ERROR_SUCCESS) {
|
| - PdhRemoveCounter(new_counters.process_id_handle);
|
| - }
|
| -
|
| - // Record the pair of counter query handles so that we can query them later.
|
| - counter_pairs_.push_back(new_counters);
|
| -}
|
| -
|
| -void PrivateWorkingSetSnapshot::Sample() {
|
| - if (counter_pairs_.empty())
|
| - return;
|
| -
|
| - // Destroy all previous data.
|
| - records_.resize(0);
|
| - // Record the requested data into PDH's internal buffers.
|
| - if (PdhCollectQueryData(query_handle_.Get()) != ERROR_SUCCESS)
|
| - return;
|
| -
|
| - for (auto& counter_pair : counter_pairs_) {
|
| - // Find out how much space is required for the two counter arrays.
|
| - // A return code of PDH_MORE_DATA indicates that we should call again with
|
| - // the buffer size returned.
|
| - DWORD buffer_size1 = 0;
|
| - DWORD item_count1 = 0;
|
| - // Process IDs should be retrieved as PDH_FMT_LONG
|
| - if (PdhGetFormattedCounterArray(counter_pair.process_id_handle,
|
| - PDH_FMT_LONG, &buffer_size1, &item_count1,
|
| - nullptr) != PDH_MORE_DATA)
|
| - continue;
|
| - if (buffer_size1 == 0 || item_count1 == 0)
|
| - continue;
|
| -
|
| - DWORD buffer_size2 = 0;
|
| - DWORD item_count2 = 0;
|
| - // Working sets should be retrieved as PDH_FMT_LARGE (LONGLONG)
|
| - // Note that if this second call to PdhGetFormattedCounterArray with the
|
| - // buffer size and count variables being zero is omitted then the PID and
|
| - // working-set results are not reliably correlated.
|
| - if (PdhGetFormattedCounterArray(counter_pair.private_ws_handle,
|
| - PDH_FMT_LARGE, &buffer_size2, &item_count2,
|
| - nullptr) != PDH_MORE_DATA)
|
| - continue;
|
| -
|
| - // It is not clear whether Pdh guarantees that the two counters in the same
|
| - // query will execute atomically - if they will see the same set of
|
| - // processes. If they do not then the correspondence between "ID Process"
|
| - // and "Working Set - Private" is lost and we have to discard these results.
|
| - // In testing these values have always matched. If this check fails then
|
| - // the old per-process memory calculations will be used instead.
|
| - if (buffer_size1 != buffer_size2 || item_count1 != item_count2)
|
| - continue;
|
| -
|
| - // Allocate enough space for the results of both queries.
|
| - std::vector<char> buffer(buffer_size1 * 2);
|
| - // Retrieve the process ID data.
|
| - auto process_id_data =
|
| - reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(&buffer[0]);
|
| - if (PdhGetFormattedCounterArray(counter_pair.process_id_handle,
|
| - PDH_FMT_LONG, &buffer_size1, &item_count1,
|
| - process_id_data) != ERROR_SUCCESS)
|
| - continue;
|
| - // Retrieve the private working set data.
|
| - auto private_ws_data =
|
| - reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(&buffer[buffer_size1]);
|
| - if (PdhGetFormattedCounterArray(counter_pair.private_ws_handle,
|
| - PDH_FMT_LARGE, &buffer_size1, &item_count1,
|
| - private_ws_data) != ERROR_SUCCESS)
|
| - continue;
|
| -
|
| - // Make room for the new set of records.
|
| - size_t start_offset = records_.size();
|
| - records_.resize(start_offset + item_count1);
|
| -
|
| - for (DWORD i = 0; i < item_count1; ++i) {
|
| - records_[start_offset + i].process_id =
|
| - process_id_data[i].FmtValue.longValue;
|
| - // Integer overflow can happen here if a 32-bit process is monitoring a
|
| - // 64-bit process so we do a saturated_cast.
|
| - records_[start_offset + i].private_ws =
|
| - base::saturated_cast<size_t>(private_ws_data[i].FmtValue.largeValue);
|
| - }
|
| - }
|
| -
|
| - // The results will include all processes that match the passed in name,
|
| - // regardless of whether they are spawned by the calling process.
|
| - // The results must be sorted by process ID for efficient lookup.
|
| - std::sort(records_.begin(), records_.end());
|
| -}
|
| -
|
| -size_t PrivateWorkingSetSnapshot::GetPrivateWorkingSet(
|
| - base::ProcessId process_id) const {
|
| - // Do a binary search for the requested process ID and return the working set
|
| - // if found.
|
| - auto p = std::lower_bound(records_.begin(), records_.end(), process_id);
|
| - if (p != records_.end() && p->process_id == process_id)
|
| - return p->private_ws;
|
| -
|
| - return 0;
|
| -}
|
|
|