Subversion Repositories shark

Rev

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