Subversion Repositories shark

Rev

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