Commit | Line | Data |
---|---|---|
77bd540c SK |
1 | #! /bin/sh |
2 | ||
3 | usage() { | |
4 | echo "EXAMPLE (whole tree) : $0 | neato -T png > ps.png && open ps.png" | |
5 | echo "EXAMPLE (user clusters): $0 | sdp -T png > ps.png && open ps.png" | |
6 | } | |
7 | ||
8 | ||
9 | compile() { | |
10 | awk -v kernel="$(uname -v)" -v whoami="$(whoami)" \ | |
11 | ' | |
4a01bf49 SK |
12 | function num_scale(src_cur, src_max, dst_min, dst_max) { |
13 | return dst_min + ((src_cur * (dst_max - dst_min)) / src_max) | |
14 | } | |
15 | ||
2940f645 | 16 | function vert_print(v, _color, _fontcolor, _shape, _state, _size, _height, _label, _label_base, _label_ext) { |
43061022 SK |
17 | _shape = "rectangle" |
18 | _state = child2state[v] | |
19 | if (_state == "D") { | |
20 | _shape = "circle" | |
21 | } else if (_state == "I") { | |
22 | _shape = "octagon" | |
23 | } else if (_state == "R") { | |
24 | _shape = "star" | |
25 | } else if (_state == "S") { | |
26 | _shape = "oval" | |
27 | } else if (_state == "T") { | |
28 | _shape = "square" | |
29 | } else if (_state == "t") { | |
30 | _shape = "Msquare" | |
31 | } else if (_state == "Z") { | |
32 | _shape = "diamond" | |
33 | } | |
4a01bf49 SK |
34 | _color =\ |
35 | num_scale(\ | |
2940f645 SK |
36 | child2cpu[v], |
37 | max_cpu, | |
38 | VERT_COLORSCHEME_MAX, | |
39 | VERT_COLORSCHEME_MIN\ | |
4a01bf49 | 40 | ) |
2940f645 SK |
41 | _size =\ |
42 | num_scale(\ | |
43 | child2mem[v], | |
44 | max_mem, | |
45 | 1, | |
46 | 5\ | |
47 | ) / 5 | |
48 | _height = _size | |
5259a527 | 49 | _fontcolor = \ |
2940f645 SK |
50 | _color == VERT_COLORSCHEME_MAX || _color == VERT_COLORSCHEME_MIN \ |
51 | ? sprintf("/%s/%d", VERT_COLORSCHEME, VERT_COLORSCHEME_MID) \ | |
5259a527 | 52 | : sprintf("/%s/%d", "greys9", 9) |
2940f645 SK |
53 | _fontcolor = \ |
54 | _size < 0.5 \ | |
55 | ? sprintf("/%s/%d", "greys9", 9) \ | |
56 | : _fontcolor | |
57 | _label_base = \ | |
58 | sprintf("%s\n%d", child2comm[v], v) | |
59 | _label_ext = \ | |
60 | _size >= 0.5 \ | |
61 | ? sprintf("\ncpu: %.1f%%\nmem: %.1f%%", child2cpu[v], child2mem[v]) \ | |
62 | : "" | |
63 | _label = _label_base _label_ext | |
4a01bf49 SK |
64 | printf(\ |
65 | "\"%d\"\ | |
66 | [ fontsize=8 \ | |
2940f645 SK |
67 | , fixedsize=true \ |
68 | , height=%f \ | |
43061022 SK |
69 | , border=1 \ |
70 | , style=\"filled,solid\" \ | |
4a01bf49 | 71 | , fontname=Helvetica \ |
2940f645 | 72 | , label=\"%s\" \ |
43061022 SK |
73 | , shape=\"%s\" \ |
74 | , fillcolor=\"/%s/%d\" \ | |
5259a527 | 75 | , fontcolor=\"%s\" \ |
4a01bf49 SK |
76 | ];", |
77 | v, | |
2940f645 SK |
78 | _height, |
79 | _label, | |
43061022 | 80 | _shape, |
2940f645 | 81 | VERT_COLORSCHEME, |
4a01bf49 | 82 | _color, |
5259a527 | 83 | _fontcolor\ |
4a01bf49 SK |
84 | ) |
85 | } | |
86 | ||
2940f645 | 87 | function edge_print(child, _parent) { |
4a01bf49 | 88 | _parent = child2parent[child] |
4a01bf49 SK |
89 | printf(\ |
90 | "\"%s\" -> \"%s\"\ | |
91 | [ fontsize=8 \ | |
92 | , fontname=Helvetica \ | |
93 | , len=2.0 \ | |
2940f645 | 94 | , color=\"%s\" \ |
4a01bf49 SK |
95 | ];\n", |
96 | _parent, | |
97 | child, | |
2940f645 | 98 | EDGE_COLOR\ |
4a01bf49 SK |
99 | ) |
100 | } | |
101 | ||
77bd540c | 102 | BEGIN { |
5259a527 SK |
103 | # Hot->Cold gradual colorschemes: |
104 | # - rdbu11 | |
105 | # - rdbu9 | |
106 | # - rdbu8 | |
2940f645 | 107 | # - rdylgn10 # 3 - 11 |
5259a527 SK |
108 | |
109 | # Light->Dark gradual colorschemes: | |
110 | # - reds9 | |
111 | # - blues9 | |
112 | # - orrd9 | |
113 | # - oranges9 | |
114 | # - bupu9 | |
115 | # - greys9 | |
116 | ||
2940f645 SK |
117 | VERT_COLORSCHEME_MIN = 1 |
118 | VERT_COLORSCHEME_MID = 4 | |
119 | VERT_COLORSCHEME_MAX = 8 | |
120 | VERT_COLORSCHEME = "rdylgn10" | |
121 | ||
122 | EDGE_COLOR = "/ylorbr9/3" | |
5259a527 | 123 | |
43061022 | 124 | child2comm[0] = "swapper/sched" |
77bd540c SK |
125 | } |
126 | ||
127 | NR > 1 { | |
4a01bf49 SK |
128 | parent2child_count[$2]++ |
129 | max_children = \ | |
130 | parent2child_count[$2] > max_children\ | |
131 | ? parent2child_count[$2]\ | |
132 | : max_children | |
133 | child2parent[$1] = $2 | |
134 | child2user_id[$1] = $3 | |
135 | child2user_name[$1] = $4 | |
5259a527 | 136 | child2nice[$1] = $5 |
43061022 | 137 | child2state[$1] = $6 |
2940f645 SK |
138 | child2cpu[$1] = $7 |
139 | child2mem[$1] = $8 | |
140 | child2comm[$1] = $9 | |
4a01bf49 | 141 | user_names[$4] = 1 |
2940f645 SK |
142 | max_cpu = $7 > max_cpu ? $7 : max_cpu |
143 | max_mem = $8 > max_mem ? $8 : max_mem | |
77bd540c SK |
144 | } |
145 | ||
146 | END { | |
147 | print "strict digraph G {"; | |
148 | ||
149 | print "start=0;"; | |
77bd540c SK |
150 | print "fontsize=8;"; |
151 | print "fontname=Helvetica;"; | |
152 | print "label=\"" kernel "\";"; | |
af6e57a2 | 153 | print "fontcolor=\"/greys9/9\";" |
77bd540c SK |
154 | |
155 | ##### Vertices (clustered by user) | |
4a01bf49 SK |
156 | for (user_name in user_names) { |
157 | printf "subgraph \"cluster_%s\" {\n", user_name | |
158 | printf "label=\"%s\"\n", user_name | |
159 | for (c in child2parent) | |
160 | if (child2user_name[c] == user_name) | |
161 | vert_print(c) | |
77bd540c SK |
162 | print "}" |
163 | } | |
164 | ||
165 | ##### Vertices (without a user) | |
43061022 | 166 | for (c in child2comm) |
4a01bf49 SK |
167 | if (!child2user_name[c]) |
168 | vert_print(c) | |
77bd540c SK |
169 | |
170 | ##### Edges (across clusters) | |
4a01bf49 SK |
171 | for (c in child2parent) |
172 | edge_print(c) | |
77bd540c SK |
173 | |
174 | print "}"; | |
175 | } | |
176 | ' | |
177 | } | |
178 | ||
179 | ||
180 | procs() { | |
181 | if [ "$(uname)" = 'Linux' ]; then | |
2940f645 | 182 | ps -eo 'pid,ppid,euid,euser,nice,s,%cpu,%mem,comm' |
77bd540c | 183 | else |
2940f645 | 184 | ps -eco 'pid,ppid,euid,euser,nice,s,%cpu,%mem,comm' |
77bd540c SK |
185 | fi |
186 | } | |
187 | ||
188 | ||
189 | main() { | |
190 | case "$1" in | |
191 | '--help') usage | |
192 | ;; | |
193 | *) procs | grep "$1" | compile | |
194 | ;; | |
195 | esac | |
196 | } | |
197 | ||
198 | ||
199 | main "$1" |