0,0 → 1,317 |
#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; |
|
} |
|