FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-150114: Log the memory usage in regrtest on Windows by vstinner · Pull Request #150267 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .h  (1) .py  (1) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
36 changes: 32 additions & 4 deletions Lib/test/libregrtest/utils.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
import sysconfig
import tempfile
import textwrap
import types
from collections.abc import Callable
_winapi: types.ModuleType | None
try:
import _winapi
except ImportError:
_winapi = None

from test import support
from test.support import os_helper
Expand Down Expand Up @@ -754,10 +760,9 @@ def display_title(title):
print(flush=True)


def get_process_memory_usage(pid: int) -> int | None:
"""
Read the private memory in bytes from /proc/pid/smaps.
"""
def _get_process_memory_usage_linux(pid: int) -> int | None:
# Linux implementation: read the private memory in bytes from
# /proc/pid/smaps.
try:
fp = open(f"/proc/{pid}/smaps", "rb")
except OSError:
Expand All @@ -775,3 +780,26 @@ def get_process_memory_usage(pid: int) -> int | None:
return total
except ProcessLookupError:
return None


def _get_process_memory_usage_windows(pid: int) -> int | None:
assert _winapi is not None # to make mypy happy
handle = _winapi.OpenProcess(_winapi.PROCESS_QUERY_LIMITED_INFORMATION,
False, pid)
try:
mem_info = _winapi.GetProcessMemoryInfo(handle)
finally:
_winapi.CloseHandle(handle)
return mem_info['WorkingSetSize']


if _winapi is not None:
get_process_memory_usage = _get_process_memory_usage_windows
elif sys.platform == 'linux':
get_process_memory_usage = _get_process_memory_usage_linux
else:
def get_process_memory_usage(pid: int) -> int | None:
"""
Get process memory usage in bytes.
"""
return None
64 changes: 64 additions & 0 deletions Modules/_winapi.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
#include <crtdbg.h>
#include "winreparse.h"

// PSAPI_VERSION=2 redirects GetProcessMemoryInfo() to
// K32GetProcessMemoryInfo() in kernel32.dll, so we don't need to link
// psapi.lib. See:
// https://learn.microsoft.com/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo
#define PSAPI_VERSION 2
#include <psapi.h> // GetProcessMemoryInfo()

#if defined(MS_WIN32) && !defined(MS_WIN64)
#define HANDLE_TO_PYNUM(handle) \
PyLong_FromUnsignedLong((unsigned long) handle)
Expand Down Expand Up @@ -3080,6 +3087,61 @@ _winapi_ReportEvent_impl(PyObject *module, HANDLE handle,
}


/*[clinic input]
_winapi.GetProcessMemoryInfo
handle: HANDLE
/

Return the memory usage of the given process handle as a dict.
[clinic start generated code]*/

static PyObject *
_winapi_GetProcessMemoryInfo_impl(PyObject *module, HANDLE handle)
/*[clinic end generated code: output=00a5d09732e84120 input=5b90ad61cdc68d2a]*/
{
PROCESS_MEMORY_COUNTERS pmc;
if (!GetProcessMemoryInfo(handle, &pmc, sizeof(pmc))) {
return PyErr_SetFromWindowsErr(0);
}

PyObject *result = PyDict_New();
if (result == NULL) {
return NULL;
}

#define ADD(ATTR) \
do { \
PyObject *obj = PyLong_FromSize_t(pmc.ATTR); \
if (obj == NULL) { \
goto error; \
} \
if (PyDict_SetItemString(result, #ATTR, obj) < 0) { \
Py_DECREF(obj); \
goto error; \
} \
Py_DECREF(obj); \
} while (0)

ADD(PageFaultCount);
ADD(PeakWorkingSetSize);
ADD(WorkingSetSize);
ADD(QuotaPeakPagedPoolUsage);
ADD(QuotaPagedPoolUsage);
ADD(QuotaPeakNonPagedPoolUsage);
ADD(QuotaNonPagedPoolUsage);
ADD(PagefileUsage);
ADD(PeakPagefileUsage);

#undef ADD

return result;

error:
Py_DECREF(result);
return NULL;
}


static PyMethodDef winapi_functions[] = {
_WINAPI_CLOSEHANDLE_METHODDEF
_WINAPI_CONNECTNAMEDPIPE_METHODDEF
Expand Down Expand Up @@ -3130,6 +3192,7 @@ static PyMethodDef winapi_functions[] = {
_WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF
_WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF
_WINAPI_COPYFILE2_METHODDEF
_WINAPI_GETPROCESSMEMORYINFO_METHODDEF
{NULL, NULL}
};

Expand Down Expand Up @@ -3226,6 +3289,7 @@ static int winapi_exec(PyObject *m)
WINAPI_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
WINAPI_CONSTANT(F_DWORD, SYNCHRONIZE);
WINAPI_CONSTANT(F_DWORD, PROCESS_DUP_HANDLE);
WINAPI_CONSTANT(F_DWORD, PROCESS_QUERY_LIMITED_INFORMATION);
WINAPI_CONSTANT(F_DWORD, SEC_COMMIT);
WINAPI_CONSTANT(F_DWORD, SEC_IMAGE);
WINAPI_CONSTANT(F_DWORD, SEC_LARGE_PAGES);
Expand Down
29 changes: 28 additions & 1 deletion Modules/clinic/_winapi.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

Back | FazBrowse Home | New Git URL