2 ##############################################################################
3 # Time-stamp: <Wed Jul 24 1996 20:35:01 Stardate: [-31]7859.07 hwloidl>
5 # Usage: gr2qp [options]
7 # Filter that transforms a GrAnSim profile (a .gr file) at stdin to
8 # a quasi-parallel profile (a .qp file). It is the common front-end for most
9 # visualization tools (except gr2pe). It collects running,
10 # runnable and blocked tasks in queues of different `colours', whose meaning
12 # G ... green; queue of all running tasks
13 # A ... amber; queue of all runnable tasks
14 # R ... red; queue of all blocked tasks
15 # Y ... cyan; queue of fetching tasks
16 # C ... crimson; queue of tasks that are being stolen
17 # B ... blue; queue of all sparks
20 # -i <int> ... info level from 1 to 7; number of queues to count (see qp3ps)
21 # -I <str> ... count tasks that are in one of the given queues; encoding:
22 # 'a' ... active (running)
28 # (e.g. -I "arb" counts sum of active, runnable, blocked tasks)
29 # -c ... check consistency of data (e.g. no neg. number of tasks)
30 # -v ... be talkative.
31 # -h ... print help message (this header).
33 ##############################################################################
37 &Getopts('hvDSci:I:');
42 do print_verbose_message();
45 # ---------------------------------------------------------------------------
47 # ---------------------------------------------------------------------------
61 $improved_sort_option = $opt_S ? "-S" : "";
63 open (FOOL,"| ghc-fool-sort $improved_sort_option | sort -n +0 -1 | ghc-unfool-sort") || die "FOOL";
67 if ( $in_header == 8 ) {
68 $start_time = $1 if /^Start-Time: (.*)$/;
72 if ( $in_header == 9 ) {
91 ($PE, $pe, $time, $act, $tid, $rest) = split;
92 $time =~ s/[\[\]:]//g;
93 # next if $act eq 'REPLY';
94 chop($tid) if $act eq 'END';
97 if ($act eq 'START') {
101 if ( $n > $pmax ) { $pmax = $n; }
103 } elsif ($act eq 'START(Q)') {
107 if ( $n > $pmax ) { $pmax = $n; }
109 } elsif ($act eq 'STEALING') {
111 } elsif ($act eq 'STOLEN') {
113 } elsif ($act eq 'STOLEN(Q)') {
115 } elsif ($act eq 'FETCH') {
117 } elsif ($act eq 'REPLY') {
119 } elsif ($act eq 'BLOCK') {
121 } elsif ($act eq 'RESUME') {
124 } elsif ($act eq 'RESUME(Q)') {
127 } elsif ($act eq 'END') {
130 if ( $opt_c && $n < 0 ) {
131 print STDERR "Error at time $time: neg. number of tasks: $n\n";
133 } elsif ($act eq 'SCHEDULE') {
135 } elsif ($act eq 'DESCHEDULE') {
137 # The following are only needed for spark profiling
138 } elsif (($act eq 'SPARK') || ($act eq 'SPARKAT')) {
141 } elsif ($act eq 'USED') {
144 } elsif ($act eq 'PRUNED') {
147 } elsif ($act eq 'EXPORTED') {
150 } elsif ($act eq 'ACQUIRED') {
154 print STDERR "Error at time $time: unknown event $act\n";
159 print STDERRR "Error at time $time: process $tid has no from queue\n";
162 print FOOL $time, " ",
163 $from, $to, " 0 0x", $tid, $extra, "\n";
167 # Compare with main loop in qp3ps
169 } elsif ($from eq 'G') {
171 } elsif ($from eq 'A') {
173 } elsif ($from eq 'R') {
175 } elsif ($from eq 'B') {
177 } elsif ($from eq 'C') {
179 } elsif ($from eq 'Y') {
182 print STDERR "Illegal from char: $from at $time\n";
186 } elsif ($to eq 'G') {
188 } elsif ($to eq 'A') {
190 } elsif ($to eq 'R') {
192 } elsif ($to eq 'B') {
194 } elsif ($to eq 'C') {
196 } elsif ($to eq 'Y') {
199 print STDERR "Illegal to char: $to at $time\n";
205 if ( $curr > $max ) {
210 print STDERR "%% $time: (act,runnable,blocked,fetch,mig,sp) = " .
211 "($active, $runnable, $blocked, $fetching, $migrating, $sparks)".
215 #print STDERR "Sparks @ $time: $sparks \tCurr: $curr \tMax: $max \n" if $opt_D;
217 if ( $time > $tmax ) {
220 delete $queue{$tid} if $to eq '*';
224 print "Time: ", $tmax, " Max_selected_tasks: ", $max,
225 " Max_running_tasks: ", $pmax, " Total_tasks: ", $ptotal, "\n";
231 # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
232 # Copied from qp3ps and slightly modified (we don't keep a list for each queue
233 # but just compute the max value we get out of all calls to count during the
234 # execution of the script).
235 # -----------------------------------------------------------------------------
237 # -----------------------------------------------------------------------------
242 return index($show,$queue)+1;
245 # -----------------------------------------------------------------------------
250 $res = (($queue_on_a) ? $active : 0) +
251 (($queue_on_r) ? $runnable : 0) +
252 (($queue_on_b) ? $blocked : 0) +
253 (($queue_on_f) ? $fetching : 0) +
254 (($queue_on_m) ? $migrating : 0) +
255 (($queue_on_s) ? $sparks : 0);
260 # -----------------------------------------------------------------------------
262 # -----------------------------------------------------------------------------
266 $active,$runnable,$blocked,$fetching,$sparks,$migrating) = @_;
268 $G[$samples] = queue_on_a ? $active : 0;
269 $A[$samples] = queue_on_r ? $runnable : 0;
270 $R[$samples] = queue_on_b ? $blocked : 0;
271 $Y[$samples] = queue_on_f ? $fetching : 0;
272 $B[$samples] = queue_on_s ? $sparks : 0;
273 $C[$samples] = queue_on_m ? $migrating : 0;
276 # -----------------------------------------------------------------------------
278 sub process_options {
280 open(ME,$0) || die "Can't open myself ($0): $!\n";
294 $show = "a" if info_level == 1;
295 $show = "ar" if info_level == 2;
296 $show = "arb" if info_level == 3;
297 $show = "arfb" if info_level == 4;
298 $show = "armfb" if info_level == 5;
299 $show = "armfbs" if info_level == 6;
310 $queue_on_a = &queue_on("a");
311 $queue_on_r = &queue_on("r");
312 $queue_on_b = &queue_on("b");
313 $queue_on_f = &queue_on("f");
314 $queue_on_s = &queue_on("s");
315 $queue_on_m = &queue_on("m");
318 sub print_verbose_message {
320 print STDERR "Info-str: $show\n";
321 print STDERR "The following queues are turned on: " .
322 ( $queue_on_a ? "active, " : "") .
323 ( $queue_on_r ? "runnable, " : "") .
324 ( $queue_on_b ? "blocked, " : "") .
325 ( $queue_on_f ? "fetching, " : "") .
326 ( $queue_on_m ? "migrating, " : "") .
327 ( $queue_on_s ? "sparks" : "") .