Subversion Repositories shark

Rev

Rev 1517 | Rev 1523 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1494 giacomo 1
#include <stdio.h>
2
#include <stdlib.h>
1499 giacomo 3
#include <math.h>
4
#include <unistd.h>
1500 giacomo 5
#include <string.h>
1494 giacomo 6
 
7
#define MAXCONTEXT 100
1520 giacomo 8
#define MAXJOB 300000
1494 giacomo 9
 
10
#define INT_CTX 1
11
#define INT_PID 9999
12
#define PID_NO_DEF -1
13
 
1495 giacomo 14
#define BACKGROUND 0
15
#define PERIODICAL 1
16
#define INTERRUPT  2
17
 
1499 giacomo 18
#define DRAW_NUM 1000
19
 
1495 giacomo 20
struct ctx_exec {
1494 giacomo 21
        int ctx;
22
        unsigned long long dtsc;
1517 giacomo 23
        unsigned long long dnsec;
24
        unsigned long long tsc_start;
25
        unsigned long long nsec_start;
1494 giacomo 26
};
27
 
1495 giacomo 28
struct ctx_to_pid {
1494 giacomo 29
        int ctx;
30
        int pid;
31
};
32
 
1495 giacomo 33
struct endcycle {
1494 giacomo 34
        int ctx;
35
        unsigned long long tsc;
1517 giacomo 36
        unsigned long long nsec;
1494 giacomo 37
};
38
 
1510 giacomo 39
void Error(int num, int line) {
40
        printf("Finite-State machine error %d at line %d\n",num,line);
1494 giacomo 41
        exit(2);
42
}
43
 
1495 giacomo 44
int context_total = 0,endcycle_total = 0,job_total = 0,exec_total = 0;
45
struct ctx_exec *exec_list;
46
struct ctx_to_pid *context_list;
47
struct endcycle *endcycle_list;
48
struct ctx_exec *job_list;
1494 giacomo 49
 
1497 giacomo 50
unsigned int clk_per_msec = 0;
1517 giacomo 51
unsigned int skip_clk_per_msec = 0;
1497 giacomo 52
 
1495 giacomo 53
unsigned long long log_start_tsc = 0;
54
unsigned long long log_end_tsc = 0;
1517 giacomo 55
unsigned long long total_tsc = 0;
56
unsigned long long total_nsec = 0;
1495 giacomo 57
 
1501 giacomo 58
/* Data for gnuplot external call */
1500 giacomo 59
int draw_data[DRAW_NUM+1];
1499 giacomo 60
 
61
int gnuplot_clear() {
62
 
63
   int i;
64
 
65
   for (i=0;i<DRAW_NUM;i++)
66
     draw_data[i] = 0;
67
 
68
   return 0;
69
 
70
}
71
 
1500 giacomo 72
int gnuplot_draw(char *title,unsigned long long max_limit,int type) {
1499 giacomo 73
 
74
   FILE *gnuplot_data, *gnuplot_command;
1500 giacomo 75
   char temp_name[30];
76
   int i,pid,*current_mem;
1499 giacomo 77
 
1500 giacomo 78
   current_mem = malloc(sizeof(int)*(DRAW_NUM+1));
79
   memcpy(current_mem,draw_data,sizeof(int)*(DRAW_NUM+1));
1499 giacomo 80
 
1500 giacomo 81
   pid = fork();
82
   if (pid == 0) {
1499 giacomo 83
 
1500 giacomo 84
     srand(getpid());
1499 giacomo 85
 
1500 giacomo 86
     sprintf(temp_name,"/tmp/pwcet%d",rand()%10000);
87
 
88
     gnuplot_data = fopen(temp_name,"w");
1504 giacomo 89
     gnuplot_command = popen("gnuplot -persist","w");
1500 giacomo 90
 
91
     for (i=0;i<DRAW_NUM;i++)
1517 giacomo 92
       fprintf(gnuplot_data,"%f\t%f\n",(double)i * (double)max_limit / (double)DRAW_NUM / 1000.0,(float)(current_mem[i]));
1500 giacomo 93
 
94
     fflush(gnuplot_data);
95
     fclose(gnuplot_data);
96
 
97
     fprintf(gnuplot_command,"set xlabel \"Time [us]\"\n");
98
     if (type == 0) {
99
        fprintf(gnuplot_command,"set ylabel \"Frequency [#]\"\n");
100
 
101
        fprintf(gnuplot_command,"plot \"%s\" using 1:2 title \"%s\" with lines\n",temp_name,title);
102
        fflush(gnuplot_command);
103
     } else {
104
       fprintf(gnuplot_command,"set ylabel \"Time [us]\"\n");
105
 
106
       fprintf(gnuplot_command,"plot \"%s\" using 1:2 title \"%s\" with lines\n",temp_name,title);
107
       fflush(gnuplot_command);
108
     }
109
 
110
     pclose(gnuplot_command);
111
     exit(0);
112
 
113
   }
114
 
1499 giacomo 115
   return 0;
116
 
117
}
118
 
1517 giacomo 119
int stats_from_execs(int ctx_num, unsigned long long *tot_nsec,
120
                                unsigned long long *min_nsec,
121
                                unsigned long long *mean_nsec,
122
                                unsigned long long *max_nsec,
123
                                unsigned long long *first_nsec,
1501 giacomo 124
                                int *number) {
125
 
1517 giacomo 126
   unsigned long long temp_nsec;
1501 giacomo 127
   int k,i;
128
 
1517 giacomo 129
   temp_nsec = 0;
130
   *max_nsec = 0;
131
   *mean_nsec = 0;
132
   *min_nsec = 0xFFFFFFFF;
133
   *first_nsec = 0;
1501 giacomo 134
   k = 0;
135
   for (i=0;i<exec_total;i++)
136
     if (exec_list[i].ctx == context_list[ctx_num].ctx) {
1517 giacomo 137
       if (*first_nsec == 0) *first_nsec = exec_list[i].nsec_start;
138
       if (exec_list[i].dnsec > *max_nsec) *max_nsec = exec_list[i].dnsec;
139
       if (exec_list[i].dnsec < *min_nsec) *min_nsec = exec_list[i].dnsec;
140
       temp_nsec += exec_list[i].dnsec;
1501 giacomo 141
       k++;
142
     }
143
 
144
   *number = k;
1517 giacomo 145
   *tot_nsec = temp_nsec;
146
   if (k != 0) *mean_nsec = temp_nsec / k;
1501 giacomo 147
 
148
   return 0;
149
 
150
}
151
 
1517 giacomo 152
int stats_from_jobs(int ctx_num, unsigned long long *tot_nsec,
153
                                unsigned long long *min_nsec,
154
                                unsigned long long *mean_nsec,
155
                                unsigned long long *max_nsec,
156
                                unsigned long long *first_nsec,
1501 giacomo 157
                                int *number) {
158
 
1517 giacomo 159
   unsigned long long temp_nsec;
1501 giacomo 160
   int k,i;
161
 
1517 giacomo 162
   temp_nsec = 0;
163
   *max_nsec = 0;
164
   *mean_nsec = 0;
165
   *min_nsec = 0xFFFFFFFF;
166
   *first_nsec = 0;
1501 giacomo 167
   k = 0;
168
   for (i=0;i<job_total;i++)
169
     if (job_list[i].ctx == context_list[ctx_num].ctx) {
1517 giacomo 170
       if (*first_nsec == 0) *first_nsec = job_list[i].nsec_start;
171
       if (job_list[i].dnsec > *max_nsec) *max_nsec = job_list[i].dnsec;
172
       if (job_list[i].dnsec < *min_nsec) *min_nsec = job_list[i].dnsec;
173
       temp_nsec += job_list[i].dnsec;
1501 giacomo 174
       k++;
175
     }
176
 
177
   *number = k;
1517 giacomo 178
   *tot_nsec = temp_nsec;
179
   if (k != 0) *mean_nsec = temp_nsec / k;
1501 giacomo 180
 
181
   return 0;
182
 
183
}
184
 
1517 giacomo 185
int arr_stats_from_execs(int ctx_num, unsigned long long *min_nsec,
186
                                unsigned long long *mean_nsec,
187
                                unsigned long long *max_nsec) {
1501 giacomo 188
 
1517 giacomo 189
   unsigned long long last_start,temp_nsec,delta_start;
1501 giacomo 190
   int i,k;
191
 
192
   last_start = 0;
1517 giacomo 193
   temp_nsec = 0;
194
   *max_nsec = 0;
195
   *min_nsec = 0xFFFFFFFF;
196
   *mean_nsec = 0;
1501 giacomo 197
   k = 0;
198
   for (i=0;i<exec_total;i++)
199
     if (exec_list[i].ctx == context_list[ctx_num].ctx) {
200
        if (last_start == 0) {
1517 giacomo 201
                last_start = exec_list[i].nsec_start;
1501 giacomo 202
        } else {
1517 giacomo 203
                delta_start = exec_list[i].nsec_start - last_start;
204
                if (delta_start > *max_nsec) *max_nsec = delta_start;
205
                if (delta_start < *min_nsec) *min_nsec = delta_start;
206
                temp_nsec += delta_start;
1501 giacomo 207
                k++;
1517 giacomo 208
                last_start = exec_list[i].nsec_start;
1501 giacomo 209
        }
210
      }
211
 
1517 giacomo 212
   if (k != 0) *mean_nsec = temp_nsec / k;
1501 giacomo 213
 
214
   return 0;
215
 
216
}
217
 
1517 giacomo 218
int arr_stats_from_jobs(int ctx_num, unsigned long long *min_nsec,
219
                                unsigned long long *mean_nsec,
220
                                unsigned long long *max_nsec) {
1501 giacomo 221
 
1517 giacomo 222
   unsigned long long last_start,temp_nsec,delta_start;
1501 giacomo 223
   int i,k;
224
 
225
   last_start = 0;
1517 giacomo 226
   temp_nsec = 0;
227
   *max_nsec = 0;
228
   *min_nsec = 0xFFFFFFFF;
229
   *mean_nsec = 0;
1501 giacomo 230
   k = 0;
231
   for (i=0;i<job_total;i++)
232
     if (job_list[i].ctx == context_list[ctx_num].ctx) {
233
        if (last_start == 0) {
1517 giacomo 234
                last_start = job_list[i].nsec_start;
1501 giacomo 235
        } else {
1517 giacomo 236
                delta_start = job_list[i].nsec_start - last_start;
237
                if (delta_start > *max_nsec) *max_nsec = delta_start;
238
                if (delta_start < *min_nsec) *min_nsec = delta_start;
239
                temp_nsec += delta_start;
1501 giacomo 240
                k++;
1517 giacomo 241
                last_start = job_list[i].nsec_start;
1501 giacomo 242
        }
243
      }
244
 
1517 giacomo 245
   if (k != 0) *mean_nsec = temp_nsec / k;
1501 giacomo 246
 
247
   return 0;
248
 
249
}
250
 
251
int plot_exec_demand_function(int ctx_num, char *pidstr) {
252
 
253
   unsigned long long max_limit;
254
   char tmpstr[50];
255
   int i;
256
 
257
   gnuplot_clear();
258
 
1517 giacomo 259
   max_limit = total_nsec;
1501 giacomo 260
 
261
   for (i=0;i<exec_total;i++)
262
     if (exec_list[i].ctx == context_list[ctx_num].ctx) {
263
       int h1,h2,h3;
264
 
1517 giacomo 265
       h1 = exec_list[i].nsec_start * DRAW_NUM / max_limit;
266
       h2 = (exec_list[i].nsec_start+exec_list[i].dnsec) * DRAW_NUM / max_limit;
1501 giacomo 267
       for (h3=h1;h3<h2;h3++)
1517 giacomo 268
         if (h3 <= DRAW_NUM) draw_data[h3] += exec_list[i].dnsec/1000*(h3-h1)/(h2-h1);
1501 giacomo 269
       for (h3=h2;h3<=DRAW_NUM;h3++)
1517 giacomo 270
         if (h3 <= DRAW_NUM) draw_data[h3] += exec_list[i].dnsec/1000;
1501 giacomo 271
 
272
     }
273
 
274
   sprintf(tmpstr,"Ctx [%d:%s] Demand-Function",context_list[ctx_num].ctx,pidstr);
275
   gnuplot_draw(tmpstr,max_limit,1);
276
 
277
   return 0;
278
 
279
}
280
 
1517 giacomo 281
int plot_exec_c_distrib(int ctx_num, unsigned long long max_nsec, char *pidstr) {
1501 giacomo 282
 
283
   unsigned long long max_limit;
284
   char tmpstr[50];
285
   int i,h;
286
 
1517 giacomo 287
   if (max_nsec == 0) return 0;
1505 giacomo 288
 
1501 giacomo 289
   gnuplot_clear();
1517 giacomo 290
 
291
   max_limit = max_nsec;
1501 giacomo 292
 
293
   for (i=0;i<exec_total;i++)
294
      if (exec_list[i].ctx == context_list[ctx_num].ctx) {
1517 giacomo 295
        h = exec_list[i].dnsec * DRAW_NUM / max_limit;
1501 giacomo 296
        if (h <= DRAW_NUM) draw_data[h]++;
297
      }
298
 
299
   sprintf(tmpstr,"Ctx [%d:%s] Exec C-dist",context_list[ctx_num].ctx,pidstr);
300
   gnuplot_draw(tmpstr,max_limit,0);
301
 
302
   return 0;
303
 
304
}
305
 
1517 giacomo 306
int plot_job_c_distrib(int ctx_num, unsigned long long max_nsec, char *pidstr) {
1501 giacomo 307
 
308
   unsigned long long max_limit;
309
   char tmpstr[50];
310
   int i,h;
311
 
1517 giacomo 312
   if (max_nsec == 0) return 0;
1505 giacomo 313
 
1501 giacomo 314
   gnuplot_clear();
315
 
1517 giacomo 316
   max_limit = max_nsec;
1501 giacomo 317
 
318
   for (i=0;i<job_total;i++)
319
      if (job_list[i].ctx == context_list[ctx_num].ctx) {
1517 giacomo 320
        h = job_list[i].dnsec * DRAW_NUM / max_limit;
1501 giacomo 321
        if (h <= DRAW_NUM) draw_data[h]++;
322
      }
323
 
324
   sprintf(tmpstr,"Ctx [%d:%s] Job C-dist",context_list[ctx_num].ctx,pidstr);
325
   gnuplot_draw(tmpstr,max_limit,0);
326
 
327
   return 0;
328
 
329
}
330
 
1517 giacomo 331
int plot_exec_arr_distrib(int ctx_num, unsigned long long max_nsec, char *pidstr) {
1501 giacomo 332
 
333
  unsigned long long max_limit,last_start,delta_start;
334
  char tmpstr[50];
335
  int i,h;
336
 
1517 giacomo 337
  if (max_nsec == 0) return 0;
1505 giacomo 338
 
1501 giacomo 339
  gnuplot_clear();
340
 
1517 giacomo 341
  max_limit = max_nsec;
1501 giacomo 342
 
343
  last_start = 0;
344
  for (i=0;i<exec_total;i++)
345
    if (exec_list[i].ctx == context_list[ctx_num].ctx) {
346
      if (last_start == 0) {
1517 giacomo 347
              last_start = exec_list[i].nsec_start;
1501 giacomo 348
      } else {
1517 giacomo 349
              delta_start = exec_list[i].nsec_start - last_start;
1501 giacomo 350
 
1517 giacomo 351
              h = delta_start * DRAW_NUM / max_limit;
1501 giacomo 352
              if (h <= DRAW_NUM) draw_data[h]++;
353
 
1517 giacomo 354
              last_start = exec_list[i].nsec_start;
1501 giacomo 355
      }
356
    }
357
 
358
  sprintf(tmpstr,"Ctx [%d:%s] Exec Arr.Delta",context_list[ctx_num].ctx,pidstr);
359
  gnuplot_draw(tmpstr,max_limit,0);
360
 
361
  return 0;
362
 
363
}
364
 
1517 giacomo 365
int plot_job_arr_distrib(int ctx_num, unsigned long long max_nsec, char *pidstr) {
1501 giacomo 366
 
367
  unsigned long long max_limit,last_start,delta_start;
368
  char tmpstr[50];
369
  int i,h;
370
 
1517 giacomo 371
  if (max_nsec == 0) return 0;
1505 giacomo 372
 
1501 giacomo 373
  gnuplot_clear();
374
 
1517 giacomo 375
  max_limit = max_nsec;
1501 giacomo 376
 
377
  last_start = 0;
378
  for (i=0;i<job_total;i++)
379
    if (job_list[i].ctx == context_list[ctx_num].ctx) {
380
      if (last_start == 0) {
1517 giacomo 381
              last_start = job_list[i].nsec_start;
1501 giacomo 382
      } else {
1517 giacomo 383
              delta_start = job_list[i].nsec_start - last_start;
1501 giacomo 384
 
1517 giacomo 385
              h = delta_start * DRAW_NUM / max_limit;
1501 giacomo 386
              if (h <= DRAW_NUM) draw_data[h]++;
387
 
1517 giacomo 388
              last_start = job_list[i].nsec_start;
1501 giacomo 389
      }
390
    }
391
 
392
  sprintf(tmpstr,"Ctx [%d:%s] Job Arr.Delta",context_list[ctx_num].ctx,pidstr);
393
  gnuplot_draw(tmpstr,max_limit,0);
394
 
395
  return 0;
396
 
397
}
398
 
1495 giacomo 399
int create_lists(char *filename) {
400
 
1494 giacomo 401
  FILE *input_file;
402
 
1495 giacomo 403
  int type,par1,par2,k,i,state;
404
 
1494 giacomo 405
  int current_context = 0;
1495 giacomo 406
  int current_exec = 0;
1494 giacomo 407
  int current_endcycle = 0;
408
 
1508 giacomo 409
  int kill_delta = 0;
410
 
1495 giacomo 411
  unsigned long long last_tsc, tsc;
1517 giacomo 412
  unsigned long long current_nsec = 0;
1494 giacomo 413
 
1495 giacomo 414
  input_file = fopen(filename,"r");
1494 giacomo 415
 
1495 giacomo 416
  /* Memory alloc */
417
  exec_list = malloc(sizeof(struct ctx_exec) * MAXJOB);
418
  context_list = malloc(sizeof(struct ctx_to_pid) * MAXCONTEXT);
419
  endcycle_list = malloc(sizeof(struct endcycle) * MAXJOB);
1494 giacomo 420
 
1495 giacomo 421
  /* Finite-State machine
422
   *
423
   * FS-Machine states:
1494 giacomo 424
 
425
 
426
        1 - Context running
427
        2 - Interrupt running
428
 
429
        10 - End
430
 
1495 giacomo 431
   */
1494 giacomo 432
 
433
  for(i=0;i<MAXCONTEXT;i++) {
1495 giacomo 434
    context_list[i].ctx = 0;
435
    context_list[i].pid = PID_NO_DEF;
1494 giacomo 436
  }
437
 
438
  /* The start context + interrupt context */
1495 giacomo 439
  context_total = 2;
1494 giacomo 440
  current_context = 0;
441
  last_tsc = 0;
442
  context_list[0].ctx = 0;
443
  context_list[0].pid = PID_NO_DEF;
444
  context_list[1].ctx = INT_CTX;
445
  context_list[1].pid = INT_PID;
446
 
447
  state = 0;
448
 
449
  k = 0;
450
  while(!feof(input_file)) {
451
 
452
    fscanf(input_file,"%d %llu",&type,&tsc);
453
    k++;
454
 
455
    switch (type) {
456
 
457
        case 1:
458
 
459
                /* No par */
460
                break;
461
 
462
        case 2:
463
        case 3:
464
        case 4:
465
        case 6:
466
        case 7:
467
        case 8:
1517 giacomo 468
        case 10:
1494 giacomo 469
 
470
                /* 1 par */
471
                fscanf(input_file,"%d",&par1);
472
                break;
473
 
474
        case 5:
1508 giacomo 475
        case 9:
1517 giacomo 476
        case 0:
1494 giacomo 477
                /* 2 par */
478
                fscanf(input_file,"%d %d",&par1,&par2);
479
                break;
480
 
481
    }
482
 
483
    switch (type) {
484
 
485
        case 0:
1510 giacomo 486
                if (state != 0) Error(1,k);
1494 giacomo 487
                printf("EVT:Log starts at [%12llu]\n",tsc);
488
                last_tsc = tsc;
489
                log_start_tsc = tsc;
1517 giacomo 490
                current_nsec = 0;
491
 
492
                if (par1 == 0) Error(11,k);
493
                if (par2 == 0) Error(12,k);
494
 
495
                current_context = par1;
496
 
497
                for (i=0;i<context_total;i++)
498
                        if (par1 == context_list[i].ctx) break;
499
                if (i == context_total) {
500
                        context_list[context_total].ctx = par1;
501
                        context_total++;
502
                }
503
 
504
                clk_per_msec = par2;
505
 
506
                exec_list[current_exec].tsc_start = tsc;
507
                exec_list[current_exec].nsec_start = current_nsec;
1494 giacomo 508
                state = 1;
509
                break;
510
 
511
        case 1:
512
                printf("EVT:Log   ends at [%12llu]\n",tsc);
1495 giacomo 513
                exec_list[current_exec].dtsc = tsc - last_tsc;
1517 giacomo 514
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec;
515
                current_nsec += exec_list[current_exec].dnsec;
1495 giacomo 516
                exec_list[current_exec].ctx = current_context;
517
                current_exec++;
1494 giacomo 518
                last_tsc = tsc;
519
                log_end_tsc = tsc;
1517 giacomo 520
                total_nsec = current_nsec;
1494 giacomo 521
                state = 10;
522
                break;
523
 
524
        /* Int start */
525
        case 2:
1510 giacomo 526
                if (state == 0) Error(2,k);
1495 giacomo 527
                exec_list[current_exec].dtsc = tsc - last_tsc;
1517 giacomo 528
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec;
529
                current_nsec += exec_list[current_exec].dnsec;
1495 giacomo 530
                exec_list[current_exec].ctx = current_context;
531
                current_exec++;
1494 giacomo 532
                last_tsc = tsc;
533
                current_context = INT_CTX;
1517 giacomo 534
                exec_list[current_exec].tsc_start = tsc - log_start_tsc;
535
                exec_list[current_exec].nsec_start = current_nsec;
1494 giacomo 536
                state = 2;
537
                break;
538
 
539
        /* Int end */
540
        case 3:
1510 giacomo 541
                if (state != 2) Error(3,k);            
1495 giacomo 542
                exec_list[current_exec].dtsc = tsc - last_tsc;
1517 giacomo 543
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec; 
544
                current_nsec += exec_list[current_exec].dnsec;
1495 giacomo 545
                exec_list[current_exec].ctx = current_context;
546
                current_exec++;
1494 giacomo 547
                last_tsc = tsc;
1511 giacomo 548
                if (par1 > 16) {
549
                  current_context = par1;
1494 giacomo 550
 
1511 giacomo 551
                  for (i=0;i<context_total;i++)
1494 giacomo 552
                        if (par1 == context_list[i].ctx) break;
1511 giacomo 553
                  if (i == context_total) {
1495 giacomo 554
                        context_list[context_total].ctx = par1;
555
                        context_total++;
1511 giacomo 556
                  }
1494 giacomo 557
                }
558
 
1517 giacomo 559
                exec_list[current_exec].tsc_start = tsc;
560
                exec_list[current_exec].nsec_start = current_nsec;
1494 giacomo 561
                state = 1;
562
                break;
563
 
564
        /* Change ctx */
565
        case 4:
566
 
1495 giacomo 567
                exec_list[current_exec].dtsc = tsc - last_tsc;
1517 giacomo 568
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec;
569
                current_nsec += exec_list[current_exec].dnsec;
1495 giacomo 570
                exec_list[current_exec].ctx = current_context;
571
                current_exec++;
1494 giacomo 572
                last_tsc = tsc;
573
                current_context = par1;
574
 
1495 giacomo 575
                for (i=0;i<context_total;i++)
1494 giacomo 576
                        if (par1 == context_list[i].ctx) break;
1495 giacomo 577
                if (i == context_total) {
578
                        context_list[context_total].ctx = par1;
579
                        context_total++;
1494 giacomo 580
                }
581
 
1517 giacomo 582
                exec_list[current_exec].tsc_start = tsc;
583
                exec_list[current_exec].nsec_start = current_nsec;
1494 giacomo 584
                state = 1;
585
                break;
586
 
587
        /* Task create */
588
        case 5:
589
 
1495 giacomo 590
                for (i=0;i<context_total;i++)
1508 giacomo 591
                        if (par1 == context_list[i].ctx) {
592
                                context_list[i].pid = par2;
593
                                break;
594
                        }
1495 giacomo 595
                if (i == context_total) {
596
                        context_list[context_total].ctx = par1;
597
                        context_list[context_total].pid = par2;
598
                        context_total++;
1494 giacomo 599
                }
600
 
601
                break;
1508 giacomo 602
 
603
        /* Task kill */
604
        case 7:
1494 giacomo 605
 
1508 giacomo 606
                for (i=0;i<context_total;i++)
607
                        if (par1 == context_list[i].ctx) break;
1510 giacomo 608
                if (i == context_total) Error(5,k);
1508 giacomo 609
                  else {
610
 
611
                        kill_delta += 1000;
612
 
613
                        for (k=0;k<current_endcycle;k++)
614
                                if (endcycle_list[k].ctx == par1)
615
                                        endcycle_list[k].ctx += kill_delta;
616
                        for (k=0;k<current_exec;k++)
617
                                if (exec_list[k].ctx == par1)
618
                                        exec_list[k].ctx += kill_delta;
619
                        context_list[context_total].ctx = context_list[i].ctx + kill_delta;
620
                        context_list[context_total].pid = context_list[i].pid;
621
                        context_total++;
622
 
623
                        if (current_context == par1) current_context += kill_delta;
624
 
625
                  }
626
 
627
                break;
628
 
1494 giacomo 629
        /* Task endcycle */
630
        case 8:
631
 
1495 giacomo 632
                for (i=0;i<context_total;i++)
1494 giacomo 633
                        if (par1 == context_list[i].ctx) break;
1510 giacomo 634
                if (i == context_total) Error(4,k);
1494 giacomo 635
 
636
                endcycle_list[current_endcycle].ctx = par1;
637
                endcycle_list[current_endcycle].tsc = tsc;
1517 giacomo 638
                endcycle_list[current_endcycle].nsec = current_nsec + (tsc-last_tsc) * 1000000 / clk_per_msec;
1494 giacomo 639
                current_endcycle++;
640
 
641
                break;
642
 
1508 giacomo 643
        /* Task id */
644
        case 9:
645
 
646
                for (i=0;i<context_total;i++)
647
                        if (par1 == context_list[i].ctx) {
648
                                context_list[i].pid = par2;
649
                                break;
650
                        }      
651
                if (i == context_total) {
652
                        context_list[context_total].ctx = par1;
653
                        context_list[context_total].pid = par2;
654
                        context_total++;
655
                }
656
 
657
                break;
658
 
1517 giacomo 659
        case 10:
660
 
661
                exec_list[current_exec].dtsc = tsc - last_tsc;
662
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec;
663
                current_nsec += exec_list[current_exec].dnsec;
664
                exec_list[current_exec].ctx = current_context;
665
                current_exec++;
666
                last_tsc = tsc;
667
 
668
                exec_list[current_exec].tsc_start = tsc;
669
                exec_list[current_exec].nsec_start = current_nsec;
670
 
671
                if (!skip_clk_per_msec) clk_per_msec = par1;
672
 
673
                break;
674
 
1494 giacomo 675
    }
676
 
1495 giacomo 677
    if (current_exec == MAXJOB-1) {
678
        printf("Too many execs...\n");
1494 giacomo 679
        exit(3);
680
    }
681
 
682
    if (current_endcycle == MAXJOB-1) {
683
        printf("Too many endcycle...\n");
684
        exit(4);
685
    }
686
 
687
    if (state == 10) break;
688
 
689
  }
690
 
1495 giacomo 691
  endcycle_total = current_endcycle;
692
  exec_total = current_exec;
1494 giacomo 693
 
1495 giacomo 694
  return k;
1494 giacomo 695
 
1495 giacomo 696
}
1494 giacomo 697
 
1495 giacomo 698
int create_job_list() {
1494 giacomo 699
 
1495 giacomo 700
  int current_job = 0, h, i, k;
701
  int temp_ctx;
1517 giacomo 702
  unsigned long long temp_nsec, endcycle_start_nsec;
703
  unsigned long long temp_tsc, endcycle_end_nsec;
1494 giacomo 704
 
1495 giacomo 705
  job_list = malloc(sizeof(struct ctx_exec) * MAXJOB);
1494 giacomo 706
 
1495 giacomo 707
  for (k=0;k<context_total;k++) {
1494 giacomo 708
 
1495 giacomo 709
    temp_ctx = context_list[k].ctx;
1517 giacomo 710
    endcycle_start_nsec = 0;
1494 giacomo 711
 
1495 giacomo 712
    for (h=0;h<endcycle_total;h++) {
1494 giacomo 713
 
1495 giacomo 714
      if (endcycle_list[h].ctx == temp_ctx) {
1494 giacomo 715
 
1517 giacomo 716
        if (endcycle_start_nsec == 0)
717
          endcycle_start_nsec = 0;
1494 giacomo 718
 
1517 giacomo 719
        endcycle_end_nsec = endcycle_list[h].nsec;
720
        temp_nsec = 0;
1494 giacomo 721
        temp_tsc = 0;
722
 
1517 giacomo 723
        job_list[current_job].nsec_start = 0;
1494 giacomo 724
 
1495 giacomo 725
        for(i=0;i<exec_total;i++)
726
                if (exec_list[i].ctx == temp_ctx) {
1517 giacomo 727
                        if (exec_list[i].nsec_start < endcycle_end_nsec &&
728
                                exec_list[i].nsec_start >= endcycle_start_nsec) {
729
                                if (job_list[current_job].nsec_start == 0)
730
                                  job_list[current_job].nsec_start = exec_list[i].nsec_start;
731
                                temp_nsec += exec_list[i].dnsec;
1495 giacomo 732
                                temp_tsc += exec_list[i].dtsc;
1494 giacomo 733
                        }
734
                }
735
 
1495 giacomo 736
        job_list[current_job].dtsc = temp_tsc;
1517 giacomo 737
        job_list[current_job].dnsec = temp_nsec;
1495 giacomo 738
        job_list[current_job].ctx = temp_ctx;
739
        current_job++;
1494 giacomo 740
 
1517 giacomo 741
        endcycle_start_nsec = endcycle_end_nsec;
1494 giacomo 742
 
1495 giacomo 743
      }
1494 giacomo 744
 
1495 giacomo 745
    }
1494 giacomo 746
 
1495 giacomo 747
  }    
748
 
749
  job_total = current_job;
750
 
1494 giacomo 751
  return 0;
752
 
753
}
754
 
1495 giacomo 755
int elaborate_statistics(int num, int task_type) {
756
 
1501 giacomo 757
  char pidstr[10];
1517 giacomo 758
  unsigned long long tot_nsec,mean_nsec,max_nsec,min_nsec,first_nsec;
1501 giacomo 759
  int number;
1495 giacomo 760
 
761
  switch (context_list[num].pid) {
762
      case PID_NO_DEF:
763
        sprintf(pidstr,"NODEF");
764
        break;
765
      case INT_PID:
766
        sprintf(pidstr,"  INT");
767
        break;
768
      default:
769
        sprintf(pidstr,"%5d",context_list[num].pid);
770
        break;
771
  }
772
 
773
  if (task_type == BACKGROUND) {
774
 
775
    printf("Background Task CTX [%5d] PID [%s]\n",context_list[num].ctx,pidstr);
776
 
1517 giacomo 777
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);    
1501 giacomo 778
 
1517 giacomo 779
    if (number > 0) {
1495 giacomo 780
 
1517 giacomo 781
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
782
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
783
      printf("    after first exec     [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
784
      printf("  Execs Number           [%12d   ]\n",number);
785
      printf("  Min  Exec              [%12llu ns]\n",min_nsec);
786
      printf("  Mean Exec              [%12llu ns]\n",mean_nsec);
787
      printf("  Max  Exec              [%12llu ns]\n\n",max_nsec);
1500 giacomo 788
 
1517 giacomo 789
      plot_exec_demand_function(num,pidstr);
790
 
791
    } else {
792
 
793
      printf("  Total Execution        [%12llu ns]\n\n",tot_nsec);
794
 
795
    }
796
 
1495 giacomo 797
  }
798
 
799
  if (task_type == INTERRUPT) {
800
 
801
    printf("Interrupts\n");
802
 
1517 giacomo 803
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);
1499 giacomo 804
 
1517 giacomo 805
    if (number > 0) {
1495 giacomo 806
 
1517 giacomo 807
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
808
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
809
      printf("    after first int      [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
810
      printf("  Interrupts Number      [%12d   ]\n",number);
811
      printf("  Min  Interrupt         [%12llu ns]\n",min_nsec);
812
      printf("  Mean Interrupt         [%12llu ns]\n",mean_nsec);
813
      printf("  Max  Interrupt         [%12llu ns]\n\n",max_nsec);
1500 giacomo 814
 
1517 giacomo 815
      plot_exec_demand_function(num,pidstr);
1499 giacomo 816
 
1517 giacomo 817
      plot_exec_c_distrib(num,max_nsec,pidstr);
1496 giacomo 818
 
1517 giacomo 819
      arr_stats_from_execs(num,&min_nsec,&mean_nsec,&max_nsec);
1499 giacomo 820
 
1517 giacomo 821
      if (max_nsec > 0) {
1505 giacomo 822
 
1517 giacomo 823
        printf("  Min  Arr. Delta        [%12llu ns]\n",min_nsec);
824
        printf("  Mean Arr. Delta        [%12llu ns]\n",mean_nsec);
825
        printf("  Max  Arr. Delta        [%12llu ns]\n\n",max_nsec);
826
 
827
        plot_exec_arr_distrib(num,max_nsec,pidstr);
828
 
829
      }
830
 
831
    } else {
832
 
833
      printf("  Total Execution        [%12llu ns]\n\n",tot_nsec);
834
 
1505 giacomo 835
    }
836
 
1495 giacomo 837
  }
838
 
839
  if (task_type == PERIODICAL) {
840
 
841
    printf("Periodical Task CTX [%5d] PID [%s]\n",context_list[num].ctx,pidstr);    
842
 
1517 giacomo 843
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);
1501 giacomo 844
 
1517 giacomo 845
    if (number > 0) {
1495 giacomo 846
 
1517 giacomo 847
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
848
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
849
      printf("    after first exec     [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
850
      printf("  Execs Number           [%12d   ]\n",number);
851
      printf("  Min  Exec              [%12llu ns]\n",min_nsec);
852
      printf("  Mean Exec              [%12llu ns]\n",mean_nsec);
853
      printf("  Max  Exec              [%12llu ns]\n\n",max_nsec);    
1500 giacomo 854
 
1517 giacomo 855
      plot_exec_demand_function(num,pidstr);
1501 giacomo 856
 
1517 giacomo 857
      stats_from_jobs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);  
1496 giacomo 858
 
1517 giacomo 859
      printf("  Total Job Exec         [%12llu ns]\n",tot_nsec);
860
      printf("  Jobs Number            [%12d   ]\n",number);
861
      printf("  Min  Job               [%12llu ns]\n",min_nsec);
862
      printf("  Mean Job               [%12llu ns]\n",mean_nsec);
863
      printf("  Max  Job               [%12llu ns]\n\n",max_nsec);
1499 giacomo 864
 
1517 giacomo 865
      plot_job_c_distrib(num,max_nsec,pidstr);
1499 giacomo 866
 
1517 giacomo 867
      arr_stats_from_jobs(num,&min_nsec,&mean_nsec,&max_nsec);
1505 giacomo 868
 
1517 giacomo 869
      if (max_nsec > 0) {
870
 
1520 giacomo 871
        printf("  Min  Arr. Delta        [%12llu ns]\n",min_nsec);
872
        printf("  Mean Arr. Delta        [%12llu ns]\n",mean_nsec);
873
        printf("  Max  Arr. Delta        [%12llu ns]\n\n",max_nsec);
1495 giacomo 874
 
1517 giacomo 875
        plot_job_arr_distrib(num,max_nsec,pidstr);
1499 giacomo 876
 
1517 giacomo 877
      }
878
 
879
    } else {
880
 
881
      printf("  Total Execution       [%12llu ns]\n\n",tot_nsec);
882
 
1505 giacomo 883
    }
884
 
1495 giacomo 885
  }
886
 
887
  return 0;
888
 
889
}
890
 
891
int main(int argc, char *argv[]) {
892
 
893
  int events_total,k,i;
894
  int task_type;
895
 
1520 giacomo 896
  unsigned long long temp_nsec;
897
 
1500 giacomo 898
  srand(getpid());
899
 
1517 giacomo 900
  if (argc < 2) {
901
    printf("%s: Enter the input file name \"%s filename.pwc [clk_per_msec]\"\n",argv[0],argv[0]);
1495 giacomo 902
    exit(1);
903
  }
904
 
905
  printf("\n");
1497 giacomo 906
 
1517 giacomo 907
  if (argc == 3) {
908
    skip_clk_per_msec = 1;
909
    clk_per_msec = atoi(argv[2]);
1520 giacomo 910
    printf("Clk/msec = %u\n\n",clk_per_msec);
1517 giacomo 911
  }
1497 giacomo 912
 
1495 giacomo 913
  events_total = create_lists(argv[1]);
914
 
1517 giacomo 915
  total_tsc = log_end_tsc - log_start_tsc;
1495 giacomo 916
 
1517 giacomo 917
  printf("\nTotal dTSC [%12llu] ns [%12llu]\n", total_tsc, total_nsec);
1499 giacomo 918
  printf("Events     [%12d]\n",events_total);
919
  printf("Execs      [%12d]\n",exec_total);
920
  printf("EndCycles  [%12d]\n",endcycle_total);
921
 
1495 giacomo 922
  printf("\nPreemption Removing.... \n");
923
 
924
  /* Remove preemption from the computation time */
925
  create_job_list();
1520 giacomo 926
 
927
  temp_nsec = 0;
928
  for (i=0;i<job_total;i++)
929
    temp_nsec += job_list[i].dnsec;
930
 
931
  printf("Total nsec of jobs [%12llu]\n",temp_nsec);
932
 
933
  temp_nsec = 0;
934
  for (i=0;i<exec_total;i++)
935
    temp_nsec += exec_list[i].dnsec;
936
 
937
  printf("Total nsec of exec [%12llu]\n",temp_nsec);
938
  printf("Total nsec considering last clk/msec [%12llu]\n",total_tsc*1000000/clk_per_msec);
939
 
1495 giacomo 940
  printf("\nCompute Task Statistics.... \n\n");
941
 
942
  for (i=0;i<context_total;i++) {
943
 
944
        task_type = BACKGROUND;
945
 
946
        if (context_list[i].ctx == INT_CTX) task_type = INTERRUPT;
947
 
948
        for (k=0;k<job_total;k++)
949
                if (job_list[k].ctx == context_list[i].ctx) {
950
                  task_type = PERIODICAL;
951
                  break;
952
                }
953
 
954
        elaborate_statistics(i,task_type);
955
 
956
  }
1500 giacomo 957
 
1495 giacomo 958
  return 0;
959
 
960
}
961