Rev 1495 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <stdio.h>
#include <stdlib.h>
#define MAXCONTEXT 100
#define MAXJOB 100000
#define INT_CTX 1
#define INT_PID 9999
#define PID_NO_DEF -1
struct single_job_exec {
int ctx;
unsigned long long dtsc;
unsigned long long start;
};
struct single_ctx {
int ctx;
int pid;
};
struct single_endcycle {
int ctx;
unsigned long long tsc;
};
void Error(int num) {
printf("Finite State machine error: %d\n",num);
exit(2);
}
int main(int argc, char *argv[]) {
FILE *input_file;
int type,par1,par2,k,i,h,temp_ctx;
unsigned long long tsc,endcycle_start_tsc,endcycle_end_tsc;
int context_number = 0;
int current_context = 0;
int current_cycle = 0;
int current_job = 0;
struct single_ctx context_list[MAXCONTEXT];
unsigned long long temp_tsc,last_tsc,log_start_tsc,log_end_tsc,total_tsc;
int state;
char pidstr[10];
int current_endcycle = 0;
struct single_job_exec *job_list;
struct single_endcycle *endcycle_list;
struct single_job_exec *cycle_list;
if (argc < 2) {
printf("%s: Enter the input file name [%s filename]\n",argv[0],argv[0]);
exit(1);
}
input_file = fopen(argv[1],"r");
/* Alloc mem */
job_list = malloc(sizeof(struct single_job_exec) * MAXJOB);
endcycle_list = malloc(sizeof(struct single_endcycle) * MAXJOB);
cycle_list = malloc(sizeof(struct single_job_exec) * MAXJOB);
/* Finite-State machine */
/* FS-Machine states:
0 - Start
1 - Context running
2 - Interrupt running
10 - End
*/
for(i=0;i<MAXCONTEXT;i++) {
context_list[i].ctx = 0;
context_list[i].pid = PID_NO_DEF;
}
/* The start context + interrupt context */
context_number = 2;
current_context = 0;
last_tsc = 0;
context_list[0].ctx = 0;
context_list[0].pid = PID_NO_DEF;
context_list[1].ctx = INT_CTX;
context_list[1].pid = INT_PID;
state = 0;
k = 0;
while(!feof(input_file)) {
fscanf(input_file,"%d %llu",&type,&tsc);
k++;
switch (type) {
case 0:
case 1:
/* No par */
break;
case 2:
case 3:
case 4:
case 6:
case 7:
case 8:
/* 1 par */
fscanf(input_file,"%d",&par1);
break;
case 5:
/* 2 par */
fscanf(input_file,"%d %d",&par1,&par2);
break;
}
switch (type) {
case 0:
if (state != 0) Error(1);
printf("EVT:Log starts at [%12llu]\n",tsc);
last_tsc = tsc;
log_start_tsc = tsc;
job_list[current_job].start = tsc;
state = 1;
break;
case 1:
printf("EVT:Log ends at [%12llu]\n",tsc);
job_list[current_job].dtsc = tsc - last_tsc;
job_list[current_job].ctx = current_context;
current_job++;
last_tsc = tsc;
log_end_tsc = tsc;
state = 10;
break;
/* Int start */
case 2:
if (state == 0) Error(2);
job_list[current_job].dtsc = tsc - last_tsc;
job_list[current_job].ctx = current_context;
current_job++;
last_tsc = tsc;
current_context = INT_CTX;
job_list[current_job].start = tsc;
state = 2;
break;
/* Int end */
case 3:
if (state != 2) Error(3);
job_list[current_job].dtsc = tsc - last_tsc;
job_list[current_job].ctx = current_context;
current_job++;
last_tsc = tsc;
current_context = par1;
for (i=0;i<context_number;i++)
if (par1 == context_list[i].ctx) break;
if (i == context_number) {
context_list[context_number].ctx = par1;
context_number++;
}
job_list[current_job].start = tsc;
state = 1;
break;
/* Change ctx */
case 4:
job_list[current_job].dtsc = tsc - last_tsc;
job_list[current_job].ctx = current_context;
current_job++;
last_tsc = tsc;
current_context = par1;
for (i=0;i<context_number;i++)
if (par1 == context_list[i].ctx) break;
if (i == context_number) {
context_list[context_number].ctx = par1;
context_number++;
}
job_list[current_job].start = tsc;
state = 1;
break;
/* Task create */
case 5:
for (i=0;i<context_number;i++)
if (par1 == context_list[i].ctx) break;
if (i == context_number) {
context_list[context_number].ctx = par1;
context_list[context_number].pid = par2;
context_number++;
}
break;
/* Task endcycle */
case 8:
for (i=0;i<context_number;i++)
if (par1 == context_list[i].ctx) break;
if (i == context_number) Error(4);
endcycle_list[current_endcycle].ctx = par1;
endcycle_list[current_endcycle].tsc = tsc;
current_endcycle++;
break;
}
if (current_job == MAXJOB-1) {
printf("Too many jobs...\n");
exit(3);
}
if (current_endcycle == MAXJOB-1) {
printf("Too many endcycle...\n");
exit(4);
}
if (state == 10) break;
}
printf("\nDelta TSC = %llu\n",log_end_tsc - log_start_tsc);
printf("Events [%8d]\n",k);
printf("Jobs [%8d]\n",current_job);
printf("EndCycles [%8d]\n",current_endcycle);
total_tsc = 0;
for (i=0;i<current_job;i++)
total_tsc += job_list[i].dtsc;
/* Jobs total execution check */
printf("\nJob TSC sum = %llu (%2.4f)\n",total_tsc,(float)total_tsc/((float)(log_end_tsc - log_start_tsc))*100.0);
/* Singel context total execution time */
for (k=0;k<context_number;k++) {
temp_tsc = 0;
for (i=0;i<current_job;i++)
if (job_list[i].ctx == context_list[k].ctx) temp_tsc += job_list[i].dtsc;
switch (context_list[k].pid) {
case PID_NO_DEF:
sprintf(pidstr,"NODEF");
break;
case INT_PID:
sprintf(pidstr," INT");
break;
default:
sprintf(pidstr,"%5d",context_list[k].pid);
break;
}
printf("Context [%5d:%s] total dTSC [%12llu]\n",context_list[k].ctx,pidstr,temp_tsc);
}
printf("\nPreemption Removing.... \n");
/* Remove preemption from the computation time */
current_cycle = 0;
endcycle_start_tsc = log_start_tsc;
for (h=0;h<current_endcycle;h++) {
endcycle_end_tsc = endcycle_list[h].tsc;
temp_ctx = endcycle_list[h].ctx;
temp_tsc = 0;
cycle_list[current_cycle].start = 0;
for(i=0;i<current_job;i++)
if (job_list[i].ctx == temp_ctx) {
if (job_list[i].start < endcycle_end_tsc &&
job_list[i].start >= endcycle_start_tsc) {
if (cycle_list[current_cycle].start == 0)
cycle_list[current_cycle].start = job_list[i].start;
temp_tsc += job_list[i].dtsc;
}
}
cycle_list[current_cycle].dtsc = temp_tsc;
cycle_list[current_cycle].ctx = temp_ctx;
current_cycle++;
endcycle_start_tsc = endcycle_end_tsc;
}
for (k=0;k<current_cycle;k++)
printf("Cycle CTX [%5d] Start [%12llu] dTSC [%12llu]\n",cycle_list[k].ctx,cycle_list[k].start,cycle_list[k].dtsc);
return 0;
}