Subversion Repositories shark

Rev

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