Skip to content

Commit 7a72e31

Browse files
committed
gh-150114: Use get_process_memory_usage() in memory watchdog
In practice, this change adds Windows and FreeBSD support to the memory watchdog.
1 parent dfe7ef6 commit 7a72e31

2 files changed

Lines changed: 39 additions & 27 deletions

File tree

Lib/test/memory_watchdog.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,35 @@
88
import sys
99
import time
1010
from test.support import get_pagesize
11+
from test.libregrtest.utils import get_process_memory_usage
1112

1213

13-
while True:
14-
page_size = get_pagesize()
15-
sys.stdin.seek(0)
16-
statm = sys.stdin.read()
17-
data = int(statm.split()[5])
18-
sys.stdout.write(" ... process data size: {data:.1f}G\n"
19-
.format(data=data * page_size / (1024 ** 3)))
20-
sys.stdout.flush()
21-
time.sleep(1)
14+
ONE_GIB = (1024 ** 3)
15+
16+
17+
def watchdog(pid):
18+
while True:
19+
mem = get_process_memory_usage(pid)
20+
if mem is None:
21+
# get_process_memory_usage() is not supported on the platform,
22+
# or something went wrong. Exit since the next call is likely to
23+
# fail the same way.
24+
return
25+
26+
sys.stdout.write(f" ... process data size: {mem / ONE_GIB:.1f} GiB\n")
27+
sys.stdout.flush()
28+
time.sleep(1)
29+
30+
def main():
31+
if len(sys.argv) != 2:
32+
print("usage: python {sys.argv[0]) pid")
33+
sys.exit(1)
34+
pid = int(sys.argv[1])
35+
36+
try:
37+
watchdog(pid)
38+
except KeyboardInterrupt:
39+
pass
40+
41+
if __name__ == "__main__":
42+
main()

Lib/test/support/__init__.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,29 +1241,20 @@ class _MemoryWatchdog:
12411241
"""
12421242

12431243
def __init__(self):
1244-
self.procfile = '/proc/{pid}/statm'.format(pid=os.getpid())
12451244
self.started = False
12461245

12471246
def start(self):
1248-
try:
1249-
f = open(self.procfile, 'r')
1250-
except OSError as e:
1251-
logging.getLogger(__name__).warning('/proc not available for stats: %s', e, exc_info=e)
1252-
sys.stderr.flush()
1253-
return
1254-
12551247
import subprocess
1256-
with f:
1257-
watchdog_script = findfile("memory_watchdog.py")
1258-
self.mem_watchdog = subprocess.Popen([sys.executable, watchdog_script],
1259-
stdin=f,
1260-
stderr=subprocess.DEVNULL)
1248+
watchdog_script = findfile("memory_watchdog.py")
1249+
cmd = [sys.executable, watchdog_script, str(os.getpid())]
1250+
self.mem_watchdog = subprocess.Popen(cmd)
12611251
self.started = True
12621252

12631253
def stop(self):
1264-
if self.started:
1265-
self.mem_watchdog.terminate()
1266-
self.mem_watchdog.wait()
1254+
if not self.started:
1255+
return
1256+
self.mem_watchdog.terminate()
1257+
self.mem_watchdog.wait()
12671258

12681259

12691260
def bigmemtest(size, memuse, dry_run=True):
@@ -1296,8 +1287,8 @@ def wrapper(self):
12961287

12971288
if real_max_memuse and verbose:
12981289
print()
1299-
print(" ... expected peak memory use: {peak:.1f}G"
1300-
.format(peak=size * memuse / (1024 ** 3)))
1290+
peak = (size * memuse) / (1024 ** 3)
1291+
print(f" ... expected peak memory use: {peak:.1f} GiB")
13011292
watchdog = _MemoryWatchdog()
13021293
watchdog.start()
13031294
else:

0 commit comments

Comments
 (0)