Subversion Repositories shark

Rev

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