Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/misc/getusage.py
4036 views
1
"""
2
Get resource usage of process
3
4
AUTHORS:
5
6
- William Stein (2006-03-04): initial version
7
"""
8
9
#############################################################################
10
# Copyright (C) 2006 William Stein <[email protected]>
11
#
12
# Distributed under the terms of the GNU General Public License (GPL)
13
#
14
# http://www.gnu.org/licenses/
15
#############################################################################
16
17
import os
18
19
def top():
20
"""
21
Return the 'top' or 'prstat' line that contains this running Sage
22
process.
23
24
OUTPUT:
25
26
- a string
27
28
EXAMPLES::
29
30
sage: top() # random output
31
'72373 python 0.0% 0:01.36 1 14+ 1197 39M+ 34M+ 55M+ 130M+'
32
33
NOTES:
34
35
The external command 'top' (http://www.unixtop.org/) is called on
36
Linux, and most other operating systems. The output format of
37
'top' is not consistent across all platforms and all versions of
38
'top'. If the :func:`top` function does not work in Sage, you may
39
need to install 'top'.
40
41
The external command 'prstat' is called on the Solaris and
42
OpenSolaris systems. That is part of Solaris, and will not need to
43
be installed. The columns used in the 'prstat' output are::
44
45
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
46
"""
47
U = os.uname()[0].lower()
48
pid = os.getpid()
49
50
if U == 'linux':
51
cmd = 'top -b -n 1 -p %s' % pid
52
elif U == 'darwin':
53
cmd = 'top -l 1 |grep "^ *%s "' % pid
54
elif U == 'sunos':
55
cmd = '/usr/bin/prstat -n 100000 1 1 | grep "^ *%s "' % pid
56
else:
57
raise NotImplementedError("top not implemented on platform %s" % U)
58
59
r = os.popen(cmd).read()
60
r = r.strip()
61
i = r.rfind('\n')
62
if i == -1:
63
return r
64
return r[i+1:]
65
66
def get_memory_usage(t=None):
67
"""
68
Return memory usage.
69
70
INPUT:
71
72
- ``t`` - a float (default: None); output of an earlier call
73
74
OUTPUT:
75
76
- ``Linux`` - Returns float number (in megabytes)
77
78
- ``OS X`` - Returns float number (in megabytes) that matches
79
VSIZE column of ``top``
80
81
- ``Solaris or OpenSolaris`` - Returns float number (in megabytes)
82
that matches RSS column of ``prstat``. Depending on the memory
83
usage, ``prstat`` will output the data in KB, MB or GB. In each
84
case, the value returned by this function will always be in MB.
85
86
- ``other`` - not implemented for any other operating systems
87
88
EXAMPLES::
89
90
sage: t = get_memory_usage(); t # random
91
873.98046875
92
93
We test that memory usage doesn't change instantly. Hopefully,
94
re-using the variable `t` means no additional memory will be
95
allocated::
96
97
sage: t = get_memory_usage()
98
sage: get_memory_usage(t)
99
0.0
100
101
.. NOTE::
102
103
* Currently, :func:`get_memory_usage` calls ``prstat`` on Solaris
104
and OpenSolaris to get the data it requires. In the long term, a
105
better solution would be to use Solaris system calls.
106
107
* In some instances, ``top`` may be used on OS X. This may break
108
if the memory usage is greater than 9999 MB. However, normally
109
``top`` is not used on OS X.
110
"""
111
U = os.uname()[0].lower()
112
if U == 'linux':
113
m = linux_memory_usage()
114
elif U == 'darwin':
115
try:
116
from sage.misc.darwin_utilities import darwin_memory_usage
117
m = float(darwin_memory_usage()) / (1024 * 1024)
118
except ImportError:
119
# darwin_utilities is not supported on some versions of OS X.
120
m = float(top().split()[-1].strip('M+'))
121
elif U == 'sunos':
122
# Sun's 'prstat' command appends K, M or G depending on whether
123
# the memory usage is in KB. MB or GB. So we need to strip off
124
# the letter, and convert to a consistent unit of MB.
125
memory_in_KB_MB_or_GB = top().split()[3]
126
if memory_in_KB_MB_or_GB.endswith("K"):
127
m = float(memory_in_KB_MB_or_GB.strip("K")) / 1024
128
elif memory_in_KB_MB_or_GB.endswith("M"):
129
m = float(memory_in_KB_MB_or_GB.strip("M"))
130
elif memory_in_KB_MB_or_GB.endswith("G"):
131
m = float(memory_in_KB_MB_or_GB.strip("G")) * 1024
132
else:
133
raise NotImplementedError("memory usage not implemented on platform %s" % U)
134
135
if t is None:
136
return m
137
else:
138
return m - t
139
140
141
142
########################################################################
143
# The following is adapted from
144
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286222
145
# Python Cookbook, by Jean Brouwers
146
########################################################################
147
148
_proc_status = '/proc/%d/status' % os.getpid()
149
150
def VmB(VmKey):
151
"""
152
Function used internally by this module.
153
"""
154
global _proc_status, _scale
155
# get pseudo file /proc/<pid>/status
156
try:
157
t = open(_proc_status)
158
v = t.read()
159
t.close()
160
except:
161
return 0.0 # non-Linux?
162
# get VmKey line e.g. 'VmRSS: 9999 kB\n ...'
163
i = v.index(VmKey)
164
v = v[i:].split(None, 3) # whitespace
165
if len(v) < 3:
166
return 0.0 # invalid format?
167
return float(v[1])/1024.0
168
169
def linux_memory_usage():
170
"""
171
Return memory usage in megabytes.
172
"""
173
return VmB('VmSize:')
174
175