xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.perf/lib/perftest/measure.py (revision 801f73adf8029e41ec107911c58034bb925796a2)
1# Copyright (C) 2013-2020 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16import time
17import os
18import gc
19
20class Measure(object):
21    """A class that measure and collect the interesting data for a given testcase.
22
23    An instance of Measure has a collection of measurements, and each
24    of them is to measure a given aspect, such as time and memory.
25    """
26
27    def __init__(self, measurements):
28        """Constructor of measure.
29
30        measurements is a collection of Measurement objects.
31        """
32
33        self.measurements = measurements
34
35    def measure(self, func, id):
36        """Measure the operations done by func with a collection of measurements."""
37        # Enable GC, force GC and disable GC before running test in order to reduce
38        # the interference from GC.
39        gc.enable()
40        gc.collect()
41        gc.disable()
42
43        for m in self.measurements:
44            m.start(id)
45
46        func()
47
48        for m in self.measurements:
49            m.stop(id)
50
51        gc.enable()
52
53    def report(self, reporter, name):
54        """Report the measured results."""
55        for m in self.measurements:
56            m.report(reporter, name)
57
58class Measurement(object):
59    """A measurement for a certain aspect."""
60
61    def __init__(self, name, result):
62        """Constructor of Measurement.
63
64        Attribute result is the TestResult associated with measurement.
65        """
66        self.name = name;
67        self.result = result
68
69    def start(self, id):
70        """Abstract method to start the measurement."""
71        raise NotImplementedError("Abstract Method:start")
72
73    def stop(self, id):
74        """Abstract method to stop the measurement.
75
76        When the measurement is stopped, we've got something, and
77        record them in result.
78        """
79        raise NotImplementedError("Abstract Method:stop.")
80
81    def report(self, reporter, name):
82        """Report the measured data by argument reporter."""
83        self.result.report(reporter, name + " " + self.name)
84
85class MeasurementCpuTime(Measurement):
86    """Measurement on CPU time."""
87    # On UNIX, time.clock() measures the amount of CPU time that has
88    # been used by the current process.  On Windows it will measure
89    # wall-clock seconds elapsed since the first call to the function.
90    # Something other than time.clock() should be used to measure CPU
91    # time on Windows.
92
93    def __init__(self, result):
94        super(MeasurementCpuTime, self).__init__("cpu_time", result)
95        self.start_time = 0
96
97    def start(self, id):
98        self.start_time = time.clock()
99
100    def stop(self, id):
101        if os.name == 'nt':
102            cpu_time = 0
103        else:
104            cpu_time = time.clock() - self.start_time
105        self.result.record (id, cpu_time)
106
107class MeasurementWallTime(Measurement):
108    """Measurement on Wall time."""
109
110    def __init__(self, result):
111        super(MeasurementWallTime, self).__init__("wall_time", result)
112        self.start_time = 0
113
114    def start(self, id):
115        self.start_time = time.time()
116
117    def stop(self, id):
118        wall_time = time.time() - self.start_time
119        self.result.record (id, wall_time)
120
121class MeasurementVmSize(Measurement):
122    """Measurement on memory usage represented by VmSize."""
123
124    def __init__(self, result):
125        super(MeasurementVmSize, self).__init__("vmsize", result)
126
127    def _compute_process_memory_usage(self, key):
128        file_path = "/proc/%d/status" % os.getpid()
129        try:
130            t = open(file_path)
131            v = t.read()
132            t.close()
133        except:
134            return 0
135        i = v.index(key)
136        v = v[i:].split(None, 3)
137        if len(v) < 3:
138            return 0
139        return int(v[1])
140
141    def start(self, id):
142        pass
143
144    def stop(self, id):
145        memory_used = self._compute_process_memory_usage("VmSize:")
146        self.result.record (id, memory_used)
147