Chromium Code Reviews| 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..d8261bf582e03305c95b63f9ebf36dc95f72288f 100644 |
| --- a/base/process/process_metrics_win.cc |
| +++ b/base/process/process_metrics_win.cc |
| @@ -171,20 +171,15 @@ class WorkingSetInformationBuffer { |
| } // namespace |
| -bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
| - size_t ws_private = 0; |
| - size_t ws_shareable = 0; |
| - size_t ws_shared = 0; |
| - |
| - DCHECK(ws_usage); |
| - memset(ws_usage, 0, sizeof(*ws_usage)); |
| - |
| - DWORD number_of_entries = 4096; // Just a guess. |
| - WorkingSetInformationBuffer buffer; |
| +// This is a helper function to get number of page entries for a process. |
| +bool GetPageEntriesNum(WorkingSetInformationBuffer& buffer, |
|
brucedawson
2016/12/05 19:22:02
The name of this function is misleading. It sounds
chengx
2016/12/06 02:51:38
Done.
|
| + const ProcessHandle& process_, |
| + DWORD* number_of_entries) { |
| int retries = 5; |
| + |
| for (;;) { |
| DWORD buffer_size = sizeof(PSAPI_WORKING_SET_INFORMATION) + |
| - (number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK)); |
| + (*number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK)); |
| if (!buffer.Reserve(buffer_size)) |
| return false; |
| @@ -196,14 +191,14 @@ bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
| if (GetLastError() != ERROR_BAD_LENGTH) |
| return false; |
| - number_of_entries = static_cast<DWORD>(buffer->NumberOfEntries); |
| + *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); |
| + *number_of_entries = static_cast<DWORD>(*number_of_entries * 1.1); |
| if (--retries == 0) { |
| // If we're looping, eventually fail. |
| @@ -214,8 +209,25 @@ bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
| // 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)); |
| + *number_of_entries = |
| + std::min(*number_of_entries, static_cast<DWORD>(buffer->NumberOfEntries)); |
| + |
| + return true; |
| +} |
| + |
| +bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
| + size_t ws_private = 0; |
| + size_t ws_shareable = 0; |
| + size_t ws_shared = 0; |
| + |
| + DCHECK(ws_usage); |
| + memset(ws_usage, 0, sizeof(*ws_usage)); |
| + |
| + DWORD number_of_entries = 4096; // Just a guess. |
|
brucedawson
2016/12/05 19:22:02
Probably no need to put this guess here. Instead h
chengx
2016/12/06 02:51:38
Done.
|
| + WorkingSetInformationBuffer buffer; |
| + if (!GetPageEntriesNum(buffer, process_, &number_of_entries)) |
| + return false; |
| + |
| for (unsigned int i = 0; i < number_of_entries; i++) { |
| if (buffer->WorkingSetInfo[i].Shared) { |
| ws_shareable++; |
| @@ -229,6 +241,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.0f; |
| + |
| + DWORD number_of_entries = 4096; // Just a guess. |
| + WorkingSetInformationBuffer buffer; |
| + if (!GetPageEntriesNum(buffer, process_, &number_of_entries)) |
| + return false; |
| + |
| + for (unsigned int i = 0; i < number_of_entries; i++) { |
| + if (buffer->WorkingSetInfo[i].Shared && |
| + buffer->WorkingSetInfo[i].ShareCount > 0) |
| + ws_pss += 1.0f / buffer->WorkingSetInfo[i].ShareCount; |
| + else |
| + ws_pss += 1.0f; |
| + } |
| + |
| + *pss_bytes = static_cast<uint64_t>(ws_pss); |
| return true; |
| } |