Rev 1510 |
Rev 1517 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <string.h>
#define MAXCONTEXT 100
#define MAXJOB 100000
#define INT_CTX 1
#define INT_PID 9999
#define PID_NO_DEF -1
#define BACKGROUND 0
#define PERIODICAL 1
#define INTERRUPT 2
#define DRAW_NUM 1000
struct ctx_exec
{
int ctx
;
unsigned long long dtsc
;
unsigned long long start
;
};
struct ctx_to_pid
{
int ctx
;
int pid
;
};
struct endcycle
{
int ctx
;
unsigned long long tsc
;
};
void Error
(int num
, int line
) {
printf("Finite-State machine error %d at line %d\n",num
,line
);
exit(2);
}
int context_total
= 0,endcycle_total
= 0,job_total
= 0,exec_total
= 0;
struct ctx_exec
*exec_list
;
struct ctx_to_pid
*context_list
;
struct endcycle
*endcycle_list
;
struct ctx_exec
*job_list
;
unsigned int clk_per_msec
= 0;
unsigned long long log_start_tsc
= 0;
unsigned long long log_end_tsc
= 0;
unsigned long long total_dtsc
= 0;
/* Data for gnuplot external call */
int draw_data
[DRAW_NUM
+1];
int gnuplot_clear
() {
int i
;
for (i
=0;i
<DRAW_NUM
;i
++)
draw_data
[i
] = 0;
return 0;
}
int gnuplot_draw
(char *title
,unsigned long long max_limit
,int type
) {
FILE
*gnuplot_data
, *gnuplot_command
;
char temp_name
[30];
int i
,pid
,*current_mem
;
current_mem
= malloc(sizeof(int)*(DRAW_NUM
+1));
memcpy(current_mem
,draw_data
,sizeof(int)*(DRAW_NUM
+1));
pid
= fork
();
if (pid
== 0) {
srand(getpid
());
sprintf(temp_name
,"/tmp/pwcet%d",rand()%10000);
gnuplot_data
= fopen(temp_name
,"w");
gnuplot_command
= popen
("gnuplot -persist","w");
for (i
=0;i
<DRAW_NUM
;i
++)
fprintf(gnuplot_data
,"%f\t%f\n",(double)i
* (double)max_limit
/ (double)DRAW_NUM
,(float)(current_mem
[i
]));
fflush(gnuplot_data
);
fclose(gnuplot_data
);
fprintf(gnuplot_command
,"set xlabel \"Time [us]\"\n");
if (type
== 0) {
fprintf(gnuplot_command
,"set ylabel \"Frequency [#]\"\n");
fprintf(gnuplot_command
,"plot \"%s\" using 1:2 title \"%s\" with lines\n",temp_name
,title
);
fflush(gnuplot_command
);
} else {
fprintf(gnuplot_command
,"set ylabel \"Time [us]\"\n");
fprintf(gnuplot_command
,"plot \"%s\" using 1:2 title \"%s\" with lines\n",temp_name
,title
);
fflush(gnuplot_command
);
}
pclose
(gnuplot_command
);
exit(0);
}
return 0;
}
int stats_from_execs
(int ctx_num
, unsigned long long *tot_tsc
,
unsigned long long *min_tsc
,
unsigned long long *mean_tsc
,
unsigned long long *max_tsc
,
unsigned long long *first_tsc
,
int *number
) {
unsigned long long temp_tsc
;
int k
,i
;
temp_tsc
= 0;
*max_tsc
= 0;
*mean_tsc
= 0;
*min_tsc
= 0xFFFFFFFF;
*first_tsc
= 0;
k
= 0;
for (i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (*first_tsc
== 0) *first_tsc
= exec_list
[i
].
start - log_start_tsc
;
if (exec_list
[i
].
dtsc > *max_tsc
) *max_tsc
= exec_list
[i
].
dtsc;
if (exec_list
[i
].
dtsc < *min_tsc
) *min_tsc
= exec_list
[i
].
dtsc;
temp_tsc
+= exec_list
[i
].
dtsc;
k
++;
}
*number
= k
;
*tot_tsc
= temp_tsc
;
if (k
!= 0) *mean_tsc
= temp_tsc
/ k
;
return 0;
}
int stats_from_jobs
(int ctx_num
, unsigned long long *tot_tsc
,
unsigned long long *min_tsc
,
unsigned long long *mean_tsc
,
unsigned long long *max_tsc
,
unsigned long long *first_tsc
,
int *number
) {
unsigned long long temp_tsc
;
int k
,i
;
temp_tsc
= 0;
*max_tsc
= 0;
*mean_tsc
= 0;
*min_tsc
= 0xFFFFFFFF;
*first_tsc
= 0;
k
= 0;
for (i
=0;i
<job_total
;i
++)
if (job_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (*first_tsc
== 0) *first_tsc
= job_list
[i
].
start - log_start_tsc
;
if (job_list
[i
].
dtsc > *max_tsc
) *max_tsc
= job_list
[i
].
dtsc;
if (job_list
[i
].
dtsc < *min_tsc
) *min_tsc
= job_list
[i
].
dtsc;
temp_tsc
+= job_list
[i
].
dtsc;
k
++;
}
*number
= k
;
*tot_tsc
= temp_tsc
;
if (k
!= 0) *mean_tsc
= temp_tsc
/ k
;
return 0;
}
int arr_stats_from_execs
(int ctx_num
, unsigned long long *min_tsc
,
unsigned long long *mean_tsc
,
unsigned long long *max_tsc
) {
unsigned long long last_start
,temp_tsc
,delta_start
;
int i
,k
;
last_start
= 0;
temp_tsc
= 0;
*max_tsc
= 0;
*min_tsc
= 0xFFFFFFFF;
*mean_tsc
= 0;
k
= 0;
for (i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (last_start
== 0) {
last_start
= exec_list
[i
].
start;
} else {
delta_start
= exec_list
[i
].
start - last_start
;
if (delta_start
> *max_tsc
) *max_tsc
= delta_start
;
if (delta_start
< *min_tsc
) *min_tsc
= delta_start
;
temp_tsc
+= delta_start
;
k
++;
last_start
= exec_list
[i
].
start;
}
}
if (k
!= 0) *mean_tsc
= temp_tsc
/ k
;
return 0;
}
int arr_stats_from_jobs
(int ctx_num
, unsigned long long *min_tsc
,
unsigned long long *mean_tsc
,
unsigned long long *max_tsc
) {
unsigned long long last_start
,temp_tsc
,delta_start
;
int i
,k
;
last_start
= 0;
temp_tsc
= 0;
*max_tsc
= 0;
*min_tsc
= 0xFFFFFFFF;
*mean_tsc
= 0;
k
= 0;
for (i
=0;i
<job_total
;i
++)
if (job_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (last_start
== 0) {
last_start
= job_list
[i
].
start;
} else {
delta_start
= job_list
[i
].
start - last_start
;
if (delta_start
> *max_tsc
) *max_tsc
= delta_start
;
if (delta_start
< *min_tsc
) *min_tsc
= delta_start
;
temp_tsc
+= delta_start
;
k
++;
last_start
= job_list
[i
].
start;
}
}
if (k
!= 0) *mean_tsc
= temp_tsc
/ k
;
return 0;
}
int plot_exec_demand_function
(int ctx_num
, char *pidstr
) {
unsigned long long max_limit
;
char tmpstr
[50];
int i
;
gnuplot_clear
();
max_limit
= total_dtsc
*1000/clk_per_msec
;
for (i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
int h1
,h2
,h3
;
h1
= ((exec_list
[i
].
start-log_start_tsc
)*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
h2
= ((exec_list
[i
].
start+exec_list
[i
].
dtsc-log_start_tsc
)*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
for (h3
=h1
;h3
<h2
;h3
++)
if (h3
<= DRAW_NUM
) draw_data
[h3
] += (exec_list
[i
].
dtsc*1000/clk_per_msec
)*(h3
-h1
)/(h2
-h1
);
for (h3
=h2
;h3
<=DRAW_NUM
;h3
++)
if (h3
<= DRAW_NUM
) draw_data
[h3
] += (exec_list
[i
].
dtsc*1000/clk_per_msec
);
}
sprintf(tmpstr
,"Ctx [%d:%s] Demand-Function",context_list
[ctx_num
].
ctx,pidstr
);
gnuplot_draw
(tmpstr
,max_limit
,1);
return 0;
}
int plot_exec_c_distrib
(int ctx_num
, unsigned long long max_tsc
, char *pidstr
) {
unsigned long long max_limit
;
char tmpstr
[50];
int i
,h
;
if (max_tsc
== 0) return 0;
gnuplot_clear
();
max_limit
= max_tsc
*1000/clk_per_msec
;
for (i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
h
= (exec_list
[i
].
dtsc*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
if (h
<= DRAW_NUM
) draw_data
[h
]++;
}
sprintf(tmpstr
,"Ctx [%d:%s] Exec C-dist",context_list
[ctx_num
].
ctx,pidstr
);
gnuplot_draw
(tmpstr
,max_limit
,0);
return 0;
}
int plot_job_c_distrib
(int ctx_num
, unsigned long long max_tsc
, char *pidstr
) {
unsigned long long max_limit
;
char tmpstr
[50];
int i
,h
;
if (max_tsc
== 0) return 0;
gnuplot_clear
();
max_limit
= max_tsc
*1000/clk_per_msec
;
for (i
=0;i
<job_total
;i
++)
if (job_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
h
= (job_list
[i
].
dtsc*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
if (h
<= DRAW_NUM
) draw_data
[h
]++;
}
sprintf(tmpstr
,"Ctx [%d:%s] Job C-dist",context_list
[ctx_num
].
ctx,pidstr
);
gnuplot_draw
(tmpstr
,max_limit
,0);
return 0;
}
int plot_exec_arr_distrib
(int ctx_num
, unsigned long long max_tsc
, char *pidstr
) {
unsigned long long max_limit
,last_start
,delta_start
;
char tmpstr
[50];
int i
,h
;
if (max_tsc
== 0) return 0;
gnuplot_clear
();
max_limit
= max_tsc
*1000/clk_per_msec
;
last_start
= 0;
for (i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (last_start
== 0) {
last_start
= exec_list
[i
].
start;
} else {
delta_start
= exec_list
[i
].
start - last_start
;
h
= (delta_start
*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
if (h
<= DRAW_NUM
) draw_data
[h
]++;
last_start
= exec_list
[i
].
start;
}
}
sprintf(tmpstr
,"Ctx [%d:%s] Exec Arr.Delta",context_list
[ctx_num
].
ctx,pidstr
);
gnuplot_draw
(tmpstr
,max_limit
,0);
return 0;
}
int plot_job_arr_distrib
(int ctx_num
, unsigned long long max_tsc
, char *pidstr
) {
unsigned long long max_limit
,last_start
,delta_start
;
char tmpstr
[50];
int i
,h
;
if (max_tsc
== 0) return 0;
gnuplot_clear
();
max_limit
= max_tsc
*1000/clk_per_msec
;
last_start
= 0;
for (i
=0;i
<job_total
;i
++)
if (job_list
[i
].
ctx == context_list
[ctx_num
].
ctx) {
if (last_start
== 0) {
last_start
= job_list
[i
].
start;
} else {
delta_start
= job_list
[i
].
start - last_start
;
h
= (delta_start
*1000/clk_per_msec
) * DRAW_NUM
/ max_limit
;
if (h
<= DRAW_NUM
) draw_data
[h
]++;
last_start
= job_list
[i
].
start;
}
}
sprintf(tmpstr
,"Ctx [%d:%s] Job Arr.Delta",context_list
[ctx_num
].
ctx,pidstr
);
gnuplot_draw
(tmpstr
,max_limit
,0);
return 0;
}
int create_lists
(char *filename
) {
FILE
*input_file
;
int type
,par1
,par2
,k
,i
,state
;
int current_context
= 0;
int current_exec
= 0;
int current_endcycle
= 0;
int kill_delta
= 0;
unsigned long long last_tsc
, tsc
;
input_file
= fopen(filename
,"r");
/* Memory alloc */
exec_list
= malloc(sizeof(struct ctx_exec
) * MAXJOB
);
context_list
= malloc(sizeof(struct ctx_to_pid
) * MAXCONTEXT
);
endcycle_list
= malloc(sizeof(struct endcycle
) * 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_total
= 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:
case 9:
/* 2 par */
fscanf(input_file
,"%d %d",&par1
,&par2
);
break;
}
switch (type
) {
case 0:
if (state
!= 0) Error
(1,k
);
printf("EVT:Log starts at [%12llu]\n",tsc
);
last_tsc
= tsc
;
log_start_tsc
= tsc
;
exec_list
[current_exec
].
start = tsc
;
state
= 1;
break;
case 1:
printf("EVT:Log ends at [%12llu]\n",tsc
);
exec_list
[current_exec
].
dtsc = tsc
- last_tsc
;
exec_list
[current_exec
].
ctx = current_context
;
current_exec
++;
last_tsc
= tsc
;
log_end_tsc
= tsc
;
state
= 10;
break;
/* Int start */
case 2:
if (state
== 0) Error
(2,k
);
exec_list
[current_exec
].
dtsc = tsc
- last_tsc
;
exec_list
[current_exec
].
ctx = current_context
;
current_exec
++;
last_tsc
= tsc
;
current_context
= INT_CTX
;
exec_list
[current_exec
].
start = tsc
;
state
= 2;
break;
/* Int end */
case 3:
if (state
!= 2) Error
(3,k
);
exec_list
[current_exec
].
dtsc = tsc
- last_tsc
;
exec_list
[current_exec
].
ctx = current_context
;
current_exec
++;
last_tsc
= tsc
;
if (par1
> 16) {
current_context
= par1
;
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) break;
if (i
== context_total
) {
context_list
[context_total
].
ctx = par1
;
context_total
++;
}
}
exec_list
[current_exec
].
start = tsc
;
state
= 1;
break;
/* Change ctx */
case 4:
exec_list
[current_exec
].
dtsc = tsc
- last_tsc
;
exec_list
[current_exec
].
ctx = current_context
;
current_exec
++;
last_tsc
= tsc
;
current_context
= par1
;
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) break;
if (i
== context_total
) {
context_list
[context_total
].
ctx = par1
;
context_total
++;
}
exec_list
[current_exec
].
start = tsc
;
state
= 1;
break;
/* Task create */
case 5:
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) {
context_list
[i
].
pid = par2
;
break;
}
if (i
== context_total
) {
context_list
[context_total
].
ctx = par1
;
context_list
[context_total
].
pid = par2
;
context_total
++;
}
break;
/* Task kill */
case 7:
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) break;
if (i
== context_total
) Error
(5,k
);
else {
kill_delta
+= 1000;
for (k
=0;k
<current_endcycle
;k
++)
if (endcycle_list
[k
].
ctx == par1
)
endcycle_list
[k
].
ctx += kill_delta
;
for (k
=0;k
<current_exec
;k
++)
if (exec_list
[k
].
ctx == par1
)
exec_list
[k
].
ctx += kill_delta
;
context_list
[context_total
].
ctx = context_list
[i
].
ctx + kill_delta
;
context_list
[context_total
].
pid = context_list
[i
].
pid;
context_total
++;
if (current_context
== par1
) current_context
+= kill_delta
;
}
break;
/* Task endcycle */
case 8:
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) break;
if (i
== context_total
) Error
(4,k
);
endcycle_list
[current_endcycle
].
ctx = par1
;
endcycle_list
[current_endcycle
].
tsc = tsc
;
current_endcycle
++;
break;
/* Task id */
case 9:
for (i
=0;i
<context_total
;i
++)
if (par1
== context_list
[i
].
ctx) {
context_list
[i
].
pid = par2
;
break;
}
if (i
== context_total
) {
context_list
[context_total
].
ctx = par1
;
context_list
[context_total
].
pid = par2
;
context_total
++;
}
break;
}
if (current_exec
== MAXJOB
-1) {
printf("Too many execs...\n");
exit(3);
}
if (current_endcycle
== MAXJOB
-1) {
printf("Too many endcycle...\n");
exit(4);
}
if (state
== 10) break;
}
endcycle_total
= current_endcycle
;
exec_total
= current_exec
;
return k
;
}
int create_job_list
() {
int current_job
= 0, h
, i
, k
;
int temp_ctx
;
unsigned long long temp_tsc
, endcycle_start_tsc
;
unsigned long long endcycle_end_tsc
;
job_list
= malloc(sizeof(struct ctx_exec
) * MAXJOB
);
for (k
=0;k
<context_total
;k
++) {
temp_ctx
= context_list
[k
].
ctx;
endcycle_start_tsc
= 0;
for (h
=0;h
<endcycle_total
;h
++) {
if (endcycle_list
[h
].
ctx == temp_ctx
) {
if (endcycle_start_tsc
== 0)
endcycle_start_tsc
= log_start_tsc
;
endcycle_end_tsc
= endcycle_list
[h
].
tsc;
temp_tsc
= 0;
job_list
[current_job
].
start = 0;
for(i
=0;i
<exec_total
;i
++)
if (exec_list
[i
].
ctx == temp_ctx
) {
if (exec_list
[i
].
start < endcycle_end_tsc
&&
exec_list
[i
].
start >= endcycle_start_tsc
) {
if (job_list
[current_job
].
start == 0)
job_list
[current_job
].
start = exec_list
[i
].
start;
temp_tsc
+= exec_list
[i
].
dtsc;
}
}
job_list
[current_job
].
dtsc = temp_tsc
;
job_list
[current_job
].
ctx = temp_ctx
;
current_job
++;
endcycle_start_tsc
= endcycle_end_tsc
;
}
}
}
job_total
= current_job
;
return 0;
}
int elaborate_statistics
(int num
, int task_type
) {
char pidstr
[10];
unsigned long long tot_tsc
,mean_tsc
,max_tsc
,min_tsc
,first_tsc
;
int number
;
switch (context_list
[num
].
pid) {
case PID_NO_DEF
:
sprintf(pidstr
,"NODEF");
break;
case INT_PID
:
sprintf(pidstr
," INT");
break;
default:
sprintf(pidstr
,"%5d",context_list
[num
].
pid);
break;
}
if (task_type
== BACKGROUND
) {
printf("Background Task CTX [%5d] PID [%s]\n",context_list
[num
].
ctx,pidstr
);
stats_from_execs
(num
,&tot_tsc
,&min_tsc
,&mean_tsc
,&max_tsc
,&first_tsc
,&number
);
printf(" Total Execution dTSC [%12llu] us [%12llu]\n",tot_tsc
,tot_tsc
*1000/clk_per_msec
);
printf(" Mean CPU Bandwidth [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
)*100.0,'%');
printf(" after first exec [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
-first_tsc
)*100.0,'%');
printf(" Execs Number [%12d]\n",number
);
printf(" Min Exec dTSC [%12llu] us [%12llu]\n",min_tsc
, min_tsc
*1000/clk_per_msec
);
printf(" Mean Exec dTSC [%12llu] us [%12llu]\n",mean_tsc
, mean_tsc
*1000/clk_per_msec
);
printf(" Max Exec dTSC [%12llu] us [%12llu]\n\n",max_tsc
, max_tsc
*1000/clk_per_msec
);
plot_exec_demand_function
(num
,pidstr
);
}
if (task_type
== INTERRUPT
) {
printf("Interrupts\n");
stats_from_execs
(num
,&tot_tsc
,&min_tsc
,&mean_tsc
,&max_tsc
,&first_tsc
,&number
);
printf(" Total Execution dTSC [%12llu] us [%12llu]\n",tot_tsc
,tot_tsc
*1000/clk_per_msec
);
printf(" Mean CPU Bandwidth [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
)*100.0,'%');
printf(" after first int [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
-first_tsc
)*100.0,'%');
printf(" Interrupts Number [%12d]\n",number
);
printf(" Min Interrupt dTSC [%12llu] us [%12llu]\n",min_tsc
,min_tsc
*1000/clk_per_msec
);
printf(" Mean Interrupt dTSC [%12llu] us [%12llu]\n",mean_tsc
,mean_tsc
*1000/clk_per_msec
);
printf(" Max Interrupt dTSC [%12llu] us [%12llu]\n\n",max_tsc
,max_tsc
*1000/clk_per_msec
);
plot_exec_c_distrib
(num
,max_tsc
,pidstr
);
arr_stats_from_execs
(num
,&min_tsc
,&mean_tsc
,&max_tsc
);
if (max_tsc
> 0) {
printf(" Min Arr. Delta dTSC [%12llu] us [%12llu]\n",min_tsc
,min_tsc
*1000/clk_per_msec
);
printf(" Mean Arr. Delta dTSC [%12llu] us [%12llu]\n",mean_tsc
,mean_tsc
*1000/clk_per_msec
);
printf(" Max Arr. Delta dTSC [%12llu] us [%12llu]\n\n",max_tsc
,max_tsc
*1000/clk_per_msec
);
plot_exec_arr_distrib
(num
,max_tsc
,pidstr
);
}
}
if (task_type
== PERIODICAL
) {
printf("Periodical Task CTX [%5d] PID [%s]\n",context_list
[num
].
ctx,pidstr
);
stats_from_execs
(num
,&tot_tsc
,&min_tsc
,&mean_tsc
,&max_tsc
,&first_tsc
,&number
);
printf(" Total Execution dTSC [%12llu] us [%12llu]\n",tot_tsc
,tot_tsc
*1000/clk_per_msec
);
printf(" Mean CPU Bandwidth [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
)*100.0,'%');
printf(" after first exec [%11f%c]\n",(double)(tot_tsc
)/(double)(total_dtsc
-first_tsc
)*100.0,'%');
printf(" Execs Number [%12d]\n",number
);
printf(" Min Exec dTSC [%12llu] us [%12llu]\n",min_tsc
,min_tsc
*1000/clk_per_msec
);
printf(" Mean Exec dTSC [%12llu] us [%12llu]\n",mean_tsc
,mean_tsc
*1000/clk_per_msec
);
printf(" Max Exec dTSC [%12llu] us [%12llu]\n\n",max_tsc
,max_tsc
*1000/clk_per_msec
);
plot_exec_demand_function
(num
,pidstr
);
stats_from_jobs
(num
,&tot_tsc
,&min_tsc
,&mean_tsc
,&max_tsc
,&first_tsc
,&number
);
printf(" Total Job Exec dTSC [%12llu] us [%12llu]\n",tot_tsc
,tot_tsc
*1000/clk_per_msec
);
printf(" Jobs Number [%12d]\n",number
);
printf(" Min Job dTSC [%12llu] us [%12llu]\n",min_tsc
,min_tsc
*1000/clk_per_msec
);
printf(" Mean Job dTSC [%12llu] us [%12llu]\n",mean_tsc
,mean_tsc
*1000/clk_per_msec
);
printf(" Max Job dTSC [%12llu] us [%12llu]\n\n",max_tsc
,max_tsc
*1000/clk_per_msec
);
plot_job_c_distrib
(num
,max_tsc
,pidstr
);
arr_stats_from_jobs
(num
,&min_tsc
,&mean_tsc
,&max_tsc
);
if (max_tsc
> 0) {
printf(" Min Arr. Delta dTSC [%12llu] us [%12llu]\n",min_tsc
,min_tsc
*1000/clk_per_msec
);
printf(" Mean Arr. Delta dTSC [%12llu] us [%12llu]\n",mean_tsc
,mean_tsc
*1000/clk_per_msec
);
printf(" Max Arr. Delta dTSC [%12llu] us [%12llu]\n\n",max_tsc
,max_tsc
*1000/clk_per_msec
);
plot_job_arr_distrib
(num
,max_tsc
,pidstr
);
}
}
return 0;
}
int main
(int argc
, char *argv
[]) {
int events_total
,k
,i
;
int task_type
;
unsigned long long total_tsc
;
srand(getpid
());
if (argc
< 3) {
printf("%s: Enter the input file name and clk_per_msec [%s filename clk_per_msec]\n",argv
[0],argv
[0]);
exit(1);
}
printf("\n");
clk_per_msec
= atoi(argv
[2]);
printf("Clk/msec = %u\n\n",clk_per_msec
);
events_total
= create_lists
(argv
[1]);
total_dtsc
= log_end_tsc
- log_start_tsc
;
printf("\nTotal dTSC [%12llu] us [%12llu]\n", total_dtsc
, total_dtsc
*1000/clk_per_msec
);
printf("Events [%12d]\n",events_total
);
printf("Execs [%12d]\n",exec_total
);
printf("EndCycles [%12d]\n",endcycle_total
);
total_tsc
= 0;
for (i
=0;i
<exec_total
;i
++)
total_tsc
+= exec_list
[i
].
dtsc;
/* Exec total execution check */
printf("\nExec TSC sum = %llu (%2.2f)\n",total_tsc
,(float)total_tsc
/((float)(log_end_tsc
- log_start_tsc
))*100.0);
printf("\nPreemption Removing.... \n");
/* Remove preemption from the computation time */
create_job_list
();
/*
for (k=0;k<job_total;k++)
printf("Job CTX [%5d] Start [%12llu] dTSC [%12llu]\n",
job_list[k].ctx,job_list[k].start,job_list[k].dtsc);
*/
printf("\nCompute Task Statistics.... \n\n");
for (i
=0;i
<context_total
;i
++) {
task_type
= BACKGROUND
;
if (context_list
[i
].
ctx == INT_CTX
) task_type
= INTERRUPT
;
for (k
=0;k
<job_total
;k
++)
if (job_list
[k
].
ctx == context_list
[i
].
ctx) {
task_type
= PERIODICAL
;
break;
}
elaborate_statistics
(i
,task_type
);
}
return 0;
}