diff options
author | Peter Kjellerstedt <peter.kjellerstedt@axis.com> | 2013-11-15 18:08:50 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-11-18 12:44:06 +0000 |
commit | d0e513d4371789d59bcb902497ca7c537a94c1f0 (patch) | |
tree | 1542d41042ac935aaaa9f6735170ffd8f9044c87 /scripts/pybootchartgui/pybootchartgui/samples.py | |
parent | a52c9b9a76371ac3f29b0355fea08b788eb2dd10 (diff) | |
download | poky-d0e513d4371789d59bcb902497ca7c537a94c1f0.tar.gz |
pybootchartgui: Import pybootchartgui 0.14.5
This update the pybootchartgui code to the latest release from its new
location at "https://github.com/mmeeks/bootchart". This only imports
the relevant parts, and not all of bootchart2.
(From OE-Core rev: 6f1568e54a7808b2ab568618fc5bb244249579f1)
Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/pybootchartgui/pybootchartgui/samples.py')
-rw-r--r-- | scripts/pybootchartgui/pybootchartgui/samples.py | 226 |
1 files changed, 142 insertions, 84 deletions
diff --git a/scripts/pybootchartgui/pybootchartgui/samples.py b/scripts/pybootchartgui/pybootchartgui/samples.py index c94b30d032..015d743aa0 100644 --- a/scripts/pybootchartgui/pybootchartgui/samples.py +++ b/scripts/pybootchartgui/pybootchartgui/samples.py | |||
@@ -1,93 +1,151 @@ | |||
1 | # This file is part of pybootchartgui. | ||
2 | |||
3 | # pybootchartgui 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 | # pybootchartgui 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 pybootchartgui. If not, see <http://www.gnu.org/licenses/>. | ||
15 | |||
16 | |||
1 | class DiskStatSample: | 17 | class DiskStatSample: |
2 | def __init__(self, time): | 18 | def __init__(self, time): |
3 | self.time = time | 19 | self.time = time |
4 | self.diskdata = [0, 0, 0] | 20 | self.diskdata = [0, 0, 0] |
5 | def add_diskdata(self, new_diskdata): | 21 | def add_diskdata(self, new_diskdata): |
6 | self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ] | 22 | self.diskdata = [ a + b for a, b in zip(self.diskdata, new_diskdata) ] |
7 | 23 | ||
8 | class CPUSample: | 24 | class CPUSample: |
9 | def __init__(self, time, user, sys, io): | 25 | def __init__(self, time, user, sys, io = 0.0, swap = 0.0): |
10 | self.time = time | 26 | self.time = time |
11 | self.user = user | 27 | self.user = user |
12 | self.sys = sys | 28 | self.sys = sys |
13 | self.io = io | 29 | self.io = io |
14 | 30 | self.swap = swap | |
15 | def __str__(self): | 31 | |
16 | return str(self.time) + "\t" + str(self.user) + "\t" + str(self.sys) + "\t" + str(self.io); | 32 | @property |
17 | 33 | def cpu(self): | |
34 | return self.user + self.sys | ||
35 | |||
36 | def __str__(self): | ||
37 | return str(self.time) + "\t" + str(self.user) + "\t" + \ | ||
38 | str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap) | ||
39 | |||
40 | class MemSample: | ||
41 | used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',) | ||
42 | |||
43 | def __init__(self, time): | ||
44 | self.time = time | ||
45 | self.records = {} | ||
46 | |||
47 | def add_value(self, name, value): | ||
48 | if name in MemSample.used_values: | ||
49 | self.records[name] = value | ||
50 | |||
51 | def valid(self): | ||
52 | keys = self.records.keys() | ||
53 | # discard incomplete samples | ||
54 | return [v for v in MemSample.used_values if v not in keys] == [] | ||
55 | |||
18 | class ProcessSample: | 56 | class ProcessSample: |
19 | def __init__(self, time, state, cpu_sample): | 57 | def __init__(self, time, state, cpu_sample): |
20 | self.time = time | 58 | self.time = time |
21 | self.state = state | 59 | self.state = state |
22 | self.cpu_sample = cpu_sample | 60 | self.cpu_sample = cpu_sample |
23 | 61 | ||
24 | def __str__(self): | 62 | def __str__(self): |
25 | return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample); | 63 | return str(self.time) + "\t" + str(self.state) + "\t" + str(self.cpu_sample) |
26 | 64 | ||
27 | class ProcessStats: | 65 | class ProcessStats: |
28 | def __init__(self, process_list, sample_period, start_time, end_time): | 66 | def __init__(self, writer, process_map, sample_count, sample_period, start_time, end_time): |
29 | self.process_list = process_list | 67 | self.process_map = process_map |
30 | self.sample_period = sample_period | 68 | self.sample_count = sample_count |
31 | self.start_time = start_time | 69 | self.sample_period = sample_period |
32 | self.end_time = end_time | 70 | self.start_time = start_time |
33 | 71 | self.end_time = end_time | |
34 | class Process: | 72 | writer.info ("%d samples, avg. sample length %f" % (self.sample_count, self.sample_period)) |
35 | def __init__(self, pid, cmd, ppid, start_time): | 73 | writer.info ("process list size: %d" % len (self.process_map.values())) |
36 | self.pid = pid | ||
37 | self.cmd = cmd.strip('(').strip(')') | ||
38 | self.ppid = ppid | ||
39 | self.start_time = start_time | ||
40 | self.samples = [] | ||
41 | self.parent = None | ||
42 | self.child_list = [] | ||
43 | |||
44 | self.duration = 0 | ||
45 | self.active = None | ||
46 | |||
47 | self.last_user_cpu_time = None | ||
48 | self.last_sys_cpu_time = None | ||
49 | |||
50 | def __str__(self): | ||
51 | return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ]) | ||
52 | |||
53 | def calc_stats(self, samplePeriod): | ||
54 | if self.samples: | ||
55 | firstSample = self.samples[0] | ||
56 | lastSample = self.samples[-1] | ||
57 | self.start_time = min(firstSample.time, self.start_time) | ||
58 | self.duration = lastSample.time - self.start_time + samplePeriod | ||
59 | |||
60 | activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] ) | ||
61 | activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] ) | ||
62 | self.active = (activeCount>2) | ||
63 | |||
64 | def calc_load(self, userCpu, sysCpu, interval): | ||
65 | |||
66 | userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval | ||
67 | sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval | ||
68 | cpuLoad = userCpuLoad + sysCpuLoad | ||
69 | # normalize | ||
70 | if cpuLoad > 1.0: | ||
71 | userCpuLoad = userCpuLoad / cpuLoad; | ||
72 | sysCpuLoad = sysCpuLoad / cpuLoad; | ||
73 | return (userCpuLoad, sysCpuLoad) | ||
74 | |||
75 | def set_parent(self, processMap): | ||
76 | if self.ppid != None: | ||
77 | self.parent = processMap.get(self.ppid) | ||
78 | if self.parent == None and self.pid > 1: | ||
79 | print "warning: no parent for pid '%i' with ppid '%i'" % (self.pid,self.ppid) | ||
80 | def get_end_time(self): | ||
81 | return self.start_time + self.duration | ||
82 | 74 | ||
83 | class DiskSample: | 75 | class Process: |
84 | def __init__(self, time, read, write, util): | 76 | def __init__(self, writer, pid, cmd, ppid, start_time): |
85 | self.time = time | 77 | self.writer = writer |
86 | self.read = read | 78 | self.pid = pid |
87 | self.write = write | 79 | self.cmd = cmd |
88 | self.util = util | 80 | self.exe = cmd |
89 | self.tput = read + write | 81 | self.args = [] |
82 | self.ppid = ppid | ||
83 | self.start_time = start_time | ||
84 | self.duration = 0 | ||
85 | self.samples = [] | ||
86 | self.parent = None | ||
87 | self.child_list = [] | ||
88 | |||
89 | self.active = None | ||
90 | self.last_user_cpu_time = None | ||
91 | self.last_sys_cpu_time = None | ||
92 | |||
93 | self.last_cpu_ns = 0 | ||
94 | self.last_blkio_delay_ns = 0 | ||
95 | self.last_swapin_delay_ns = 0 | ||
96 | |||
97 | # split this process' run - triggered by a name change | ||
98 | def split(self, writer, pid, cmd, ppid, start_time): | ||
99 | split = Process (writer, pid, cmd, ppid, start_time) | ||
100 | |||
101 | split.last_cpu_ns = self.last_cpu_ns | ||
102 | split.last_blkio_delay_ns = self.last_blkio_delay_ns | ||
103 | split.last_swapin_delay_ns = self.last_swapin_delay_ns | ||
104 | |||
105 | return split | ||
106 | |||
107 | def __str__(self): | ||
108 | return " ".join([str(self.pid), self.cmd, str(self.ppid), '[ ' + str(len(self.samples)) + ' samples ]' ]) | ||
90 | 109 | ||
91 | def __str__(self): | 110 | def calc_stats(self, samplePeriod): |
92 | return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)]) | 111 | if self.samples: |
112 | firstSample = self.samples[0] | ||
113 | lastSample = self.samples[-1] | ||
114 | self.start_time = min(firstSample.time, self.start_time) | ||
115 | self.duration = lastSample.time - self.start_time + samplePeriod | ||
116 | |||
117 | activeCount = sum( [1 for sample in self.samples if sample.cpu_sample and sample.cpu_sample.sys + sample.cpu_sample.user + sample.cpu_sample.io > 0.0] ) | ||
118 | activeCount = activeCount + sum( [1 for sample in self.samples if sample.state == 'D'] ) | ||
119 | self.active = (activeCount>2) | ||
120 | |||
121 | def calc_load(self, userCpu, sysCpu, interval): | ||
122 | userCpuLoad = float(userCpu - self.last_user_cpu_time) / interval | ||
123 | sysCpuLoad = float(sysCpu - self.last_sys_cpu_time) / interval | ||
124 | cpuLoad = userCpuLoad + sysCpuLoad | ||
125 | # normalize | ||
126 | if cpuLoad > 1.0: | ||
127 | userCpuLoad = userCpuLoad / cpuLoad | ||
128 | sysCpuLoad = sysCpuLoad / cpuLoad | ||
129 | return (userCpuLoad, sysCpuLoad) | ||
130 | |||
131 | def set_parent(self, processMap): | ||
132 | if self.ppid != None: | ||
133 | self.parent = processMap.get (self.ppid) | ||
134 | if self.parent == None and self.pid // 1000 > 1 and \ | ||
135 | not (self.ppid == 2000 or self.pid == 2000): # kernel threads: ppid=2 | ||
136 | self.writer.warn("Missing CONFIG_PROC_EVENTS: no parent for pid '%i' ('%s') with ppid '%i'" \ | ||
137 | % (self.pid,self.cmd,self.ppid)) | ||
138 | |||
139 | def get_end_time(self): | ||
140 | return self.start_time + self.duration | ||
141 | |||
142 | class DiskSample: | ||
143 | def __init__(self, time, read, write, util): | ||
144 | self.time = time | ||
145 | self.read = read | ||
146 | self.write = write | ||
147 | self.util = util | ||
148 | self.tput = read + write | ||
93 | 149 | ||
150 | def __str__(self): | ||
151 | return "\t".join([str(self.time), str(self.read), str(self.write), str(self.util)]) | ||