Subversion Repositories shark

Rev

Rev 1560 | Details | Compare with Previous | Last modification | View Log | RSS feed

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