Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Unified Diff: base/process/process_metrics_win.cc

Issue 2549803003: Add function to compute proportional set size for OS_WIN (Closed)
Patch Set: Fix compile error for std::min Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/process/process_metrics.h ('k') | components/tracing/common/process_metrics_memory_dump_provider.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/process/process_metrics_win.cc
diff --git a/base/process/process_metrics_win.cc b/base/process/process_metrics_win.cc
index 5b2777bb364bfa1c53679432fd511acfb8dbd4a4..d2f0c935531071a092289637b9696a744c22ea9a 100644
--- a/base/process/process_metrics_win.cc
+++ b/base/process/process_metrics_win.cc
@@ -155,9 +155,58 @@ class WorkingSetInformationBuffer {
return UncheckedMalloc(size, reinterpret_cast<void**>(&buffer_));
}
- PSAPI_WORKING_SET_INFORMATION* get() { return buffer_; }
const PSAPI_WORKING_SET_INFORMATION* operator ->() const { return buffer_; }
+ size_t GetPageEntryCount() const { return number_of_entries; }
+
+ // This function is used to get page entries for a process.
+ bool QueryPageEntries(const ProcessHandle& process_) {
+ int retries = 5;
+ number_of_entries = 4096; // Just a guess.
+
+ for (;;) {
+ size_t buffer_size =
+ sizeof(PSAPI_WORKING_SET_INFORMATION) +
+ (number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK));
+
+ if (!Reserve(buffer_size))
+ return false;
+
+ // On success, |buffer_| is populated with info about the working set of
+ // |process_|. On ERROR_BAD_LENGTH failure, increase the size of the
+ // buffer and try again.
+ if (QueryWorkingSet(process_, buffer_, buffer_size))
+ break; // Success
+
+ if (GetLastError() != ERROR_BAD_LENGTH)
+ return false;
+
+ number_of_entries = buffer_->NumberOfEntries;
+
+ // Maybe some entries are being added right now. Increase the buffer to
+ // take that into account. Increasing by 10% should generally be enough,
+ // especially considering the potentially low memory condition during the
+ // call (when called from OomMemoryDetails) and the potentially high
+ // number of entries (300K was observed in crash dumps).
+ number_of_entries *= 1.1;
+
+ if (--retries == 0) {
+ // If we're looping, eventually fail.
+ return false;
+ }
+ }
+
+ // TODO(chengx): Remove the comment and the logic below. It is no longer
+ // needed since we don't have Win2000 support.
+ // On windows 2000 the function returns 1 even when the buffer is too small.
+ // The number of entries that we are going to parse is the minimum between
+ // the size we allocated and the real number of entries.
+ number_of_entries = std::min(number_of_entries,
+ static_cast<size_t>(buffer_->NumberOfEntries));
+
+ return true;
+ }
+
private:
void Clear() {
free(buffer_);
@@ -166,6 +215,9 @@ class WorkingSetInformationBuffer {
PSAPI_WORKING_SET_INFORMATION* buffer_ = nullptr;
+ // Number of page entries.
+ size_t number_of_entries = 0;
+
DISALLOW_COPY_AND_ASSIGN(WorkingSetInformationBuffer);
};
@@ -179,44 +231,12 @@ bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
DCHECK(ws_usage);
memset(ws_usage, 0, sizeof(*ws_usage));
- DWORD number_of_entries = 4096; // Just a guess.
WorkingSetInformationBuffer buffer;
- int retries = 5;
- for (;;) {
- DWORD buffer_size = sizeof(PSAPI_WORKING_SET_INFORMATION) +
- (number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK));
-
- if (!buffer.Reserve(buffer_size))
- return false;
-
- // Call the function once to get number of items
- if (QueryWorkingSet(process_, buffer.get(), buffer_size))
- break; // Success
-
- if (GetLastError() != ERROR_BAD_LENGTH)
- return false;
-
- number_of_entries = static_cast<DWORD>(buffer->NumberOfEntries);
-
- // Maybe some entries are being added right now. Increase the buffer to
- // take that into account. Increasing by 10% should generally be enough,
- // especially considering the potentially low memory condition during the
- // call (when called from OomMemoryDetails) and the potentially high
- // number of entries (300K was observed in crash dumps).
- number_of_entries = static_cast<DWORD>(number_of_entries * 1.1);
-
- if (--retries == 0) {
- // If we're looping, eventually fail.
- return false;
- }
- }
+ if (!buffer.QueryPageEntries(process_))
+ return false;
- // On windows 2000 the function returns 1 even when the buffer is too small.
- // The number of entries that we are going to parse is the minimum between the
- // size we allocated and the real number of entries.
- number_of_entries =
- std::min(number_of_entries, static_cast<DWORD>(buffer->NumberOfEntries));
- for (unsigned int i = 0; i < number_of_entries; i++) {
+ size_t num_page_entries = buffer.GetPageEntryCount();
+ for (size_t i = 0; i < num_page_entries; i++) {
if (buffer->WorkingSetInfo[i].Shared) {
ws_shareable++;
if (buffer->WorkingSetInfo[i].ShareCount > 1)
@@ -229,6 +249,28 @@ bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
ws_usage->priv = ws_private * PAGESIZE_KB;
ws_usage->shareable = ws_shareable * PAGESIZE_KB;
ws_usage->shared = ws_shared * PAGESIZE_KB;
+
+ return true;
+}
+
+// This function calculates the proportional set size for a process.
+bool ProcessMetrics::GetProportionalSetSizeBytes(uint64_t* pss_bytes) const {
+ double ws_pss = 0.0;
+
+ WorkingSetInformationBuffer buffer;
+ if (!buffer.QueryPageEntries(process_))
+ return false;
+
+ size_t num_page_entries = buffer.GetPageEntryCount();
+ for (size_t i = 0; i < num_page_entries; i++) {
+ if (buffer->WorkingSetInfo[i].Shared &&
+ buffer->WorkingSetInfo[i].ShareCount > 0)
+ ws_pss += 1.0 / buffer->WorkingSetInfo[i].ShareCount;
+ else
+ ws_pss += 1.0;
+ }
+
+ *pss_bytes = static_cast<uint64_t>(ws_pss * GetPageSize());
return true;
}
« no previous file with comments | « base/process/process_metrics.h ('k') | components/tracing/common/process_metrics_memory_dump_provider.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698