Subversion Repositories shark

Rev

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
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:
1494 giacomo 518
                /* 1 par */
519
                fscanf(input_file,"%d",&par1);
520
                break;
521
 
522
        case 5:
1508 giacomo 523
        case 9:
1517 giacomo 524
        case 0:
1560 trimarchi 525
        case 16:
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 */
1560 trimarchi 706
        case 16:
1558 trimarchi 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
                }
1560 trimarchi 717
                printf("(%d, %d, %d)", ctx_server_total, par1, par2);
1558 trimarchi 718
                break;
719
 
1523 giacomo 720
        /* Deadline miss */
721
        case 20:
722
 
723
                for (i=0;i<context_total;i++)
724
                        if (par1 == context_list[i].ctx) break;
1532 giacomo 725
                //if (i == context_total) Error(4,k);
1523 giacomo 726
 
727
                deadline_miss_list[deadline_miss].ctx = par1;
728
                deadline_miss_list[deadline_miss].tsc = tsc;
729
                deadline_miss_list[deadline_miss].nsec = current_nsec + (tsc-last_tsc) * 1000000 / clk_per_msec;
730
                deadline_miss++;
731
 
732
                break;
733
 
734
        /* Wcet miss */
735
        case 21:
736
 
737
                for (i=0;i<context_total;i++)
738
                        if (par1 == context_list[i].ctx) break;
1532 giacomo 739
                //if (i == context_total) Error(4,k);
1523 giacomo 740
 
741
                wcet_miss_list[wcet_miss].ctx = par1;
742
                wcet_miss_list[wcet_miss].tsc = tsc;
743
                wcet_miss_list[wcet_miss].nsec = current_nsec + (tsc-last_tsc) * 1000000 / clk_per_msec;
744
                wcet_miss++;
745
 
746
                break;
747
 
1508 giacomo 748
        /* Task id */
749
        case 9:
750
 
751
                for (i=0;i<context_total;i++)
752
                        if (par1 == context_list[i].ctx) {
753
                                context_list[i].pid = par2;
754
                                break;
755
                        }      
756
                if (i == context_total) {
757
                        context_list[context_total].ctx = par1;
758
                        context_list[context_total].pid = par2;
759
                        context_total++;
760
                }
761
 
762
                break;
763
 
1517 giacomo 764
        case 10:
765
 
766
                exec_list[current_exec].dtsc = tsc - last_tsc;
767
                exec_list[current_exec].dnsec = exec_list[current_exec].dtsc * 1000000 / clk_per_msec;
768
                current_nsec += exec_list[current_exec].dnsec;
769
                exec_list[current_exec].ctx = current_context;
770
                current_exec++;
771
                last_tsc = tsc;
772
 
773
                exec_list[current_exec].tsc_start = tsc;
774
                exec_list[current_exec].nsec_start = current_nsec;
775
 
776
                if (!skip_clk_per_msec) clk_per_msec = par1;
777
 
778
                break;
779
 
1494 giacomo 780
    }
781
 
1495 giacomo 782
    if (current_exec == MAXJOB-1) {
783
        printf("Too many execs...\n");
1494 giacomo 784
        exit(3);
785
    }
786
 
1523 giacomo 787
    if (current_endcycle == MAXJOB-1 || act_total == MAXJOB-1
788
        || deadline_miss == MAXJOB-1 || wcet_miss == MAXJOB-1) {
789
        printf("Too many jobs...\n");
1494 giacomo 790
        exit(4);
791
    }
792
 
793
    if (state == 10) break;
794
 
795
  }
796
 
1495 giacomo 797
  endcycle_total = current_endcycle;
798
  exec_total = current_exec;
1494 giacomo 799
 
1495 giacomo 800
  return k;
1494 giacomo 801
 
1495 giacomo 802
}
1494 giacomo 803
 
1523 giacomo 804
int task_events(int num, int *act, int *dlinemiss, int *wcetmiss) {
805
 
806
  unsigned long long i;
807
  int tmp = 0;
808
 
809
  *act = 0;
810
  *dlinemiss = 0;
811
  *wcetmiss = 0;
812
 
813
  tmp = 0;
814
  for (i=0;i<act_total;i++)
815
    if (act_list[i].ctx == context_list[num].ctx) tmp++;
816
  *act = tmp;
817
  tmp = 0;
818
  for (i=0;i<deadline_miss;i++)
819
    if (deadline_miss_list[i].ctx == context_list[num].ctx) tmp++;
820
  *dlinemiss = tmp;
821
  tmp = 0;
822
  for (i=0;i<wcet_miss;i++)
823
    if (wcet_miss_list[i].ctx == context_list[num].ctx) tmp++;
824
  *wcetmiss = tmp;
825
 
826
  return 0;
827
 
828
}
829
 
1495 giacomo 830
int create_job_list() {
1494 giacomo 831
 
1495 giacomo 832
  int current_job = 0, h, i, k;
833
  int temp_ctx;
1517 giacomo 834
  unsigned long long temp_nsec, endcycle_start_nsec;
835
  unsigned long long temp_tsc, endcycle_end_nsec;
1494 giacomo 836
 
1495 giacomo 837
  job_list = malloc(sizeof(struct ctx_exec) * MAXJOB);
1494 giacomo 838
 
1495 giacomo 839
  for (k=0;k<context_total;k++) {
1494 giacomo 840
 
1495 giacomo 841
    temp_ctx = context_list[k].ctx;
1517 giacomo 842
    endcycle_start_nsec = 0;
1494 giacomo 843
 
1495 giacomo 844
    for (h=0;h<endcycle_total;h++) {
1494 giacomo 845
 
1495 giacomo 846
      if (endcycle_list[h].ctx == temp_ctx) {
1494 giacomo 847
 
1517 giacomo 848
        if (endcycle_start_nsec == 0)
849
          endcycle_start_nsec = 0;
1494 giacomo 850
 
1517 giacomo 851
        endcycle_end_nsec = endcycle_list[h].nsec;
852
        temp_nsec = 0;
1494 giacomo 853
        temp_tsc = 0;
854
 
1517 giacomo 855
        job_list[current_job].nsec_start = 0;
1494 giacomo 856
 
1495 giacomo 857
        for(i=0;i<exec_total;i++)
858
                if (exec_list[i].ctx == temp_ctx) {
1517 giacomo 859
                        if (exec_list[i].nsec_start < endcycle_end_nsec &&
860
                                exec_list[i].nsec_start >= endcycle_start_nsec) {
861
                                if (job_list[current_job].nsec_start == 0)
862
                                  job_list[current_job].nsec_start = exec_list[i].nsec_start;
863
                                temp_nsec += exec_list[i].dnsec;
1495 giacomo 864
                                temp_tsc += exec_list[i].dtsc;
1494 giacomo 865
                        }
866
                }
867
 
1495 giacomo 868
        job_list[current_job].dtsc = temp_tsc;
1517 giacomo 869
        job_list[current_job].dnsec = temp_nsec;
1495 giacomo 870
        job_list[current_job].ctx = temp_ctx;
871
        current_job++;
1494 giacomo 872
 
1517 giacomo 873
        endcycle_start_nsec = endcycle_end_nsec;
1494 giacomo 874
 
1495 giacomo 875
      }
1494 giacomo 876
 
1495 giacomo 877
    }
1494 giacomo 878
 
1495 giacomo 879
  }    
880
 
881
  job_total = current_job;
882
 
1494 giacomo 883
  return 0;
884
 
885
}
886
 
1495 giacomo 887
int elaborate_statistics(int num, int task_type) {
888
 
1501 giacomo 889
  char pidstr[10];
1558 trimarchi 890
  char serverstr[10];
1517 giacomo 891
  unsigned long long tot_nsec,mean_nsec,max_nsec,min_nsec,first_nsec;
1523 giacomo 892
  int number,act,dlinemiss,wcetmiss;
1558 trimarchi 893
  int i=0;
1495 giacomo 894
 
895
  switch (context_list[num].pid) {
896
      case PID_NO_DEF:
897
        sprintf(pidstr,"NODEF");
898
        break;
899
      case INT_PID:
900
        sprintf(pidstr,"  INT");
901
        break;
902
      default:
903
        sprintf(pidstr,"%5d",context_list[num].pid);
904
        break;
905
  }
906
 
1558 trimarchi 907
  for (i=0; i<ctx_server_total; i++) {
1560 trimarchi 908
    if (ctx_server_list[i].ctx==context_list[num].ctx) {
1558 trimarchi 909
      sprintf(serverstr,"%5d", ctx_server_list[i].server_id);
1560 trimarchi 910
      break;
911
    }
1558 trimarchi 912
  }
913
 
914
  if (i==ctx_server_total)
915
    sprintf(serverstr, "NODEF");
916
 
917
 
1495 giacomo 918
  if (task_type == BACKGROUND) {
919
 
1558 trimarchi 920
    printf("Background Task CTX [%5d] PID [%s] SERVER [%s]\n",context_list[num].ctx,pidstr, serverstr);
1495 giacomo 921
 
1517 giacomo 922
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);    
1501 giacomo 923
 
1517 giacomo 924
    if (number > 0) {
1495 giacomo 925
 
1517 giacomo 926
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
927
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
928
      printf("    after first exec     [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
929
      printf("  Execs Number           [%12d   ]\n",number);
930
      printf("  Min  Exec              [%12llu ns]\n",min_nsec);
931
      printf("  Mean Exec              [%12llu ns]\n",mean_nsec);
932
      printf("  Max  Exec              [%12llu ns]\n\n",max_nsec);
1500 giacomo 933
 
1517 giacomo 934
      plot_exec_demand_function(num,pidstr);
935
 
936
    } else {
937
 
938
      printf("  Total Execution        [%12llu ns]\n\n",tot_nsec);
939
 
940
    }
941
 
1495 giacomo 942
  }
943
 
944
  if (task_type == INTERRUPT) {
945
 
946
    printf("Interrupts\n");
947
 
1517 giacomo 948
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);
1499 giacomo 949
 
1517 giacomo 950
    if (number > 0) {
1495 giacomo 951
 
1517 giacomo 952
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
953
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
954
      printf("    after first int      [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
955
      printf("  Interrupts Number      [%12d   ]\n",number);
956
      printf("  Min  Interrupt         [%12llu ns]\n",min_nsec);
957
      printf("  Mean Interrupt         [%12llu ns]\n",mean_nsec);
958
      printf("  Max  Interrupt         [%12llu ns]\n\n",max_nsec);
1500 giacomo 959
 
1517 giacomo 960
      plot_exec_demand_function(num,pidstr);
1499 giacomo 961
 
1517 giacomo 962
      plot_exec_c_distrib(num,max_nsec,pidstr);
1496 giacomo 963
 
1517 giacomo 964
      arr_stats_from_execs(num,&min_nsec,&mean_nsec,&max_nsec);
1499 giacomo 965
 
1517 giacomo 966
      if (max_nsec > 0) {
1505 giacomo 967
 
1517 giacomo 968
        printf("  Min  Arr. Delta        [%12llu ns]\n",min_nsec);
969
        printf("  Mean Arr. Delta        [%12llu ns]\n",mean_nsec);
970
        printf("  Max  Arr. Delta        [%12llu ns]\n\n",max_nsec);
971
 
972
        plot_exec_arr_distrib(num,max_nsec,pidstr);
973
 
974
      }
975
 
976
    } else {
977
 
978
      printf("  Total Execution        [%12llu ns]\n\n",tot_nsec);
979
 
1505 giacomo 980
    }
981
 
1495 giacomo 982
  }
983
 
984
  if (task_type == PERIODICAL) {
985
 
1560 trimarchi 986
    printf("Periodical Task CTX [%5d] PID [%s] SERVER [%s]\n",context_list[num].ctx,pidstr,serverstr);    
1495 giacomo 987
 
1517 giacomo 988
    stats_from_execs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);
1501 giacomo 989
 
1517 giacomo 990
    if (number > 0) {
1495 giacomo 991
 
1517 giacomo 992
      printf("  Total Execution        [%12llu ns]\n",tot_nsec);
993
      printf("  Mean  CPU Bandwidth    [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec)*100.0,'%');
994
      printf("    after first exec     [%11f%c   ]\n",(double)(tot_nsec)/(double)(total_nsec-first_nsec)*100.0,'%');
995
      printf("  Execs Number           [%12d   ]\n",number);
996
      printf("  Min  Exec              [%12llu ns]\n",min_nsec);
997
      printf("  Mean Exec              [%12llu ns]\n",mean_nsec);
998
      printf("  Max  Exec              [%12llu ns]\n\n",max_nsec);    
1500 giacomo 999
 
1517 giacomo 1000
      plot_exec_demand_function(num,pidstr);
1501 giacomo 1001
 
1517 giacomo 1002
      stats_from_jobs(num,&tot_nsec,&min_nsec,&mean_nsec,&max_nsec,&first_nsec,&number);  
1496 giacomo 1003
 
1517 giacomo 1004
      printf("  Total Job Exec         [%12llu ns]\n",tot_nsec);
1005
      printf("  Jobs Number            [%12d   ]\n",number);
1006
      printf("  Min  Job               [%12llu ns]\n",min_nsec);
1007
      printf("  Mean Job               [%12llu ns]\n",mean_nsec);
1008
      printf("  Max  Job               [%12llu ns]\n\n",max_nsec);
1499 giacomo 1009
 
1523 giacomo 1010
      task_events(num,&act,&dlinemiss,&wcetmiss);
1011
 
1012
      printf("  Activations            [%12d   ]\n",act);
1013
      printf("  Deadline Miss          [%12d   ]\n",dlinemiss);
1014
      printf("  Wcet Miss              [%12d   ]\n\n",wcetmiss);
1015
 
1517 giacomo 1016
      plot_job_c_distrib(num,max_nsec,pidstr);
1499 giacomo 1017
 
1517 giacomo 1018
      arr_stats_from_jobs(num,&min_nsec,&mean_nsec,&max_nsec);
1505 giacomo 1019
 
1517 giacomo 1020
      if (max_nsec > 0) {
1021
 
1520 giacomo 1022
        printf("  Min  Arr. Delta        [%12llu ns]\n",min_nsec);
1023
        printf("  Mean Arr. Delta        [%12llu ns]\n",mean_nsec);
1024
        printf("  Max  Arr. Delta        [%12llu ns]\n\n",max_nsec);
1495 giacomo 1025
 
1517 giacomo 1026
        plot_job_arr_distrib(num,max_nsec,pidstr);
1499 giacomo 1027
 
1517 giacomo 1028
      }
1029
 
1030
    } else {
1031
 
1032
      printf("  Total Execution       [%12llu ns]\n\n",tot_nsec);
1033
 
1505 giacomo 1034
    }
1035
 
1495 giacomo 1036
  }
1037
 
1038
  return 0;
1039
 
1040
}
1041
 
1042
int main(int argc, char *argv[]) {
1043
 
1044
  int events_total,k,i;
1045
  int task_type;
1046
 
1520 giacomo 1047
  unsigned long long temp_nsec;
1048
 
1500 giacomo 1049
  srand(getpid());
1050
 
1517 giacomo 1051
  if (argc < 2) {
1052
    printf("%s: Enter the input file name \"%s filename.pwc [clk_per_msec]\"\n",argv[0],argv[0]);
1495 giacomo 1053
    exit(1);
1054
  }
1055
 
1056
  printf("\n");
1497 giacomo 1057
 
1517 giacomo 1058
  if (argc == 3) {
1059
    skip_clk_per_msec = 1;
1060
    clk_per_msec = atoi(argv[2]);
1520 giacomo 1061
    printf("Clk/msec = %u\n\n",clk_per_msec);
1517 giacomo 1062
  }
1497 giacomo 1063
 
1495 giacomo 1064
  events_total = create_lists(argv[1]);
1065
 
1517 giacomo 1066
  total_tsc = log_end_tsc - log_start_tsc;
1495 giacomo 1067
 
1517 giacomo 1068
  printf("\nTotal dTSC [%12llu] ns [%12llu]\n", total_tsc, total_nsec);
1499 giacomo 1069
  printf("Events     [%12d]\n",events_total);
1070
  printf("Execs      [%12d]\n",exec_total);
1071
  printf("EndCycles  [%12d]\n",endcycle_total);
1523 giacomo 1072
  printf("Dline miss [%12d]\n",deadline_miss);
1073
  printf("WCET miss  [%12d]\n",wcet_miss);
1499 giacomo 1074
 
1495 giacomo 1075
  printf("\nPreemption Removing.... \n");
1076
 
1077
  /* Remove preemption from the computation time */
1078
  create_job_list();
1520 giacomo 1079
 
1080
  temp_nsec = 0;
1081
  for (i=0;i<job_total;i++)
1082
    temp_nsec += job_list[i].dnsec;
1083
 
1084
  printf("Total nsec of jobs [%12llu]\n",temp_nsec);
1085
 
1086
  temp_nsec = 0;
1087
  for (i=0;i<exec_total;i++)
1088
    temp_nsec += exec_list[i].dnsec;
1089
 
1090
  printf("Total nsec of exec [%12llu]\n",temp_nsec);
1091
  printf("Total nsec considering last clk/msec [%12llu]\n",total_tsc*1000000/clk_per_msec);
1092
 
1495 giacomo 1093
  printf("\nCompute Task Statistics.... \n\n");
1094
 
1095
  for (i=0;i<context_total;i++) {
1096
 
1097
        task_type = BACKGROUND;
1098
 
1099
        if (context_list[i].ctx == INT_CTX) task_type = INTERRUPT;
1100
 
1101
        for (k=0;k<job_total;k++)
1102
                if (job_list[k].ctx == context_list[i].ctx) {
1103
                  task_type = PERIODICAL;
1104
                  break;
1105
                }
1106
 
1107
        elaborate_statistics(i,task_type);
1108
 
1109
  }
1500 giacomo 1110
 
1495 giacomo 1111
  return 0;
1112
 
1113
}
1114