Rev 1215 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#include <kernel/kern.h>
#include "parser.h"
#include "dosread.h"
#include "fsf_contract.h"
#include "fsf_server.h"
/* Memory pointers on loaded file */
extern void *start_file
;
extern void *end_file
;
/* Calibration Loops */
#define CALIBRATION_DELTA 10000
/* Mutex number */
#define MAX_MUTEX 10
/* Activate task output */
#define TASK_OUTPUT
struct timespec zero_time
;
int cal_cycles
= 0;
mutex_t mux_table
[MAX_MUTEX
];
/* Not Real-Time Task */
TASK nrt_test_task
(void *arg
)
{
long long i
,exec_cycles
= 0;
int exec_1
,exec_2
,exec_3
;
int act_1
,act_2
,act_3
,next_act
;
int crit_1
= 0,crit_2
= 0,crit_3
= 0,crit_4
= 0;
int crit_start
,crit_len
;
long long crit_start_cycles
= 0, crit_len_cycles
= 0;
struct timespec next_time
;
struct loader_task
*l
= (struct loader_task
*)(arg
);
char tmp
[20];
act_1
= TIMESPEC2USEC
(&l
->act_par_2
);
act_2
= TIMESPEC2USEC
(&l
->act_par_3
);
act_3
= TIMESPEC2USEC
(&l
->act_par_4
);
if (l
->act_type
== PAR_ACT_PERIODIC
) {
kern_gettime
(&next_time
);
ADDUSEC2TIMESPEC
(act_1
,&next_time
);
kern_event_post
(&next_time
,(void *)((void *)task_activate
),(void *)exec_shadow
);
}
if (l
->act_type
== PAR_ACT_MEAN
) {
next_act
= act_1
+ rand() % act_2
- act_2
/2;
kern_gettime
(&next_time
);
ADDUSEC2TIMESPEC
(next_act
,&next_time
);
kern_event_post
(&next_time
,(void *)((void *)task_activate
),(void *)exec_shadow
);
}
if (l
->act_type
== PAR_ACT_GAUSS
) {
}
if (l
->act_type
== PAR_ACT_GAUSS_MAX
) {
}
exec_1
= TIMESPEC2USEC
(&l
->exec_par_1
);
exec_2
= TIMESPEC2USEC
(&l
->exec_par_2
);
exec_3
= TIMESPEC2USEC
(&l
->exec_par_3
);
if (l
->crit_type
== PAR_CRIT
) {
crit_1
= TIMESPEC2USEC
(&l
->crit_par_1
);
crit_2
= TIMESPEC2USEC
(&l
->crit_par_2
);
crit_3
= TIMESPEC2USEC
(&l
->crit_par_3
);
crit_4
= TIMESPEC2USEC
(&l
->crit_par_4
);
}
#ifdef TASK_OUTPUT
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
, "R[000000]");
#endif
if (l
->exec_type
== PAR_EXEC_CONST
)
exec_cycles
= (long long)(exec_1
) * CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_MEAN
)
exec_cycles
= (long long)(exec_1
+ rand() % exec_2
- exec_2
/2)
* CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_GAUSS
)
exec_cycles
= 0;
if (l
->exec_type
== PAR_EXEC_GAUSS_MAX
)
exec_cycles
= 0;
if (l
->crit_type
== PAR_CRIT
) {
crit_start
= crit_1
+ rand() % crit_2
- crit_2
/2;
crit_len
= crit_3
+ rand() % crit_4
- crit_4
/2;
crit_start_cycles
= (long long)(crit_start
) * CALIBRATION_DELTA
/ cal_cycles
;
crit_len_cycles
= (long long)(crit_len
) * CALIBRATION_DELTA
/ cal_cycles
;
exec_cycles
-= crit_start_cycles
+ crit_len_cycles
;
if (exec_cycles
< 0) {
cprintf
("Error: exec_cycles < 0\n");
sys_end
();
}
}
if (l
->crit_type
== PAR_NO_CRIT
)
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
else {
for (i
=0;i
<crit_start_cycles
;i
++) kern_gettime
(NULL
);
#ifdef TASK_OUTPUT
sprintf(tmp
,"B[%02d][%02d]",exec_shadow
,l
->resource
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, RED
,tmp
);
#endif
mutex_lock
(&mux_table
[l
->resource
]);
for (i
=0;i
<crit_len_cycles
;i
++) kern_gettime
(NULL
);
mutex_unlock
(&mux_table
[l
->resource
]);
#ifdef TASK_OUTPUT
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
,"R[000000]");
#endif
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
}
#ifdef TASK_OUTPUT
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, BLUE
, "E[000000]");
#endif
return NULL
;
}
/* Soft and hard Task */
TASK test_task
(void *arg
)
{
long long i
,exec_cycles
= 0;
int exec_1
,exec_2
,exec_3
;
int act_1
,act_2
,act_3
,next_act
;
int crit_1
= 0,crit_2
= 0,crit_3
= 0,crit_4
= 0;
int crit_start
,crit_len
;
long long crit_start_cycles
= 0, crit_len_cycles
= 0;
struct timespec next_time
;
int act
= 0;
struct loader_task
*l
= (struct loader_task
*)(arg
);
char tmp
[20];
act_1
= TIMESPEC2USEC
(&l
->act_par_2
);
act_2
= TIMESPEC2USEC
(&l
->act_par_3
);
act_3
= TIMESPEC2USEC
(&l
->act_par_4
);
exec_1
= TIMESPEC2USEC
(&l
->exec_par_1
);
exec_2
= TIMESPEC2USEC
(&l
->exec_par_2
);
exec_3
= TIMESPEC2USEC
(&l
->exec_par_3
);
if (l
->crit_type
== PAR_CRIT
) {
crit_1
= TIMESPEC2USEC
(&l
->crit_par_1
);
crit_2
= TIMESPEC2USEC
(&l
->crit_par_2
);
crit_3
= TIMESPEC2USEC
(&l
->crit_par_3
);
crit_4
= TIMESPEC2USEC
(&l
->crit_par_4
);
}
while(1) {
task_testcancel
();
act
++;
#ifdef TASK_OUTPUT
sprintf(tmp
,"X[%06d]",act
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
, tmp
);
#endif
if (l
->act_type
== PAR_ACT_MEAN
) {
next_act
= act_1
+ rand() % act_2
- act_2
/2;
kern_gettime
(&next_time
);
ADDUSEC2TIMESPEC
(next_act
,&next_time
);
kern_event_post
(&next_time
,(void *)((void *)task_activate
),(void *)exec_shadow
);
}
if (l
->act_type
== PAR_ACT_GAUSS
) {
}
if (l
->act_type
== PAR_ACT_GAUSS_MAX
) {
}
if (l
->exec_type
== PAR_EXEC_CONST
)
exec_cycles
= (long long)(exec_1
) * CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_MEAN
)
exec_cycles
= (long long)(exec_1
+ rand() % exec_2
- exec_2
/2)
* CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_GAUSS
)
exec_cycles
= 0;
if (l
->exec_type
== PAR_EXEC_GAUSS_MAX
)
exec_cycles
= 0;
if (l
->crit_type
== PAR_CRIT
) {
crit_start
= crit_1
+ rand() % crit_2
- crit_2
/2;
crit_len
= crit_3
+ rand() % crit_4
- crit_4
/2;
crit_start_cycles
= (long long)(crit_start
) * CALIBRATION_DELTA
/ cal_cycles
;
crit_len_cycles
= (long long)(crit_len
) * CALIBRATION_DELTA
/ cal_cycles
;
exec_cycles
-= crit_start_cycles
+ crit_len_cycles
;
if (exec_cycles
< 0) {
cprintf
("Error: exec_cycles < 0\n");
sys_end
();
}
}
if (l
->crit_type
== PAR_NO_CRIT
)
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
else {
for (i
=0;i
<crit_start_cycles
;i
++) kern_gettime
(NULL
);
#ifdef TASK_OUTPUT
sprintf(tmp
,"B[%02d][%02d]",exec_shadow
,l
->resource
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, RED
, tmp
);
#endif
mutex_lock
(&mux_table
[l
->resource
]);
for (i
=0;i
<crit_len_cycles
;i
++) kern_gettime
(NULL
);
mutex_unlock
(&mux_table
[l
->resource
]);
#ifdef TASK_OUTPUT
sprintf(tmp
,"X[%06d]",act
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
, tmp
);
#endif
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
}
task_endcycle
();
}
return NULL
;
}
/* Background Task */
TASK back_task
(void *arg
)
{
long long i
,exec_cycles
= 0;
int exec_1
,exec_2
,exec_3
;
int act_1
,act_2
,act_3
,next_act
;
int crit_1
= 0,crit_2
= 0,crit_3
= 0,crit_4
= 0;
int crit_start
,crit_len
;
long long crit_start_cycles
= 0, crit_len_cycles
= 0;
struct timespec next_time
;
int act
= 0;
struct loader_task
*l
= (struct loader_task
*)(arg
);
char tmp
[20];
act_1
= TIMESPEC2USEC
(&l
->act_par_2
);
act_2
= TIMESPEC2USEC
(&l
->act_par_3
);
act_3
= TIMESPEC2USEC
(&l
->act_par_4
);
exec_1
= TIMESPEC2USEC
(&l
->exec_par_1
);
exec_2
= TIMESPEC2USEC
(&l
->exec_par_2
);
exec_3
= TIMESPEC2USEC
(&l
->exec_par_3
);
if (l
->crit_type
== PAR_CRIT
) {
crit_1
= TIMESPEC2USEC
(&l
->crit_par_1
);
crit_2
= TIMESPEC2USEC
(&l
->crit_par_2
);
crit_3
= TIMESPEC2USEC
(&l
->crit_par_3
);
crit_4
= TIMESPEC2USEC
(&l
->crit_par_4
);
}
while(1) {
task_testcancel
();
act
++;
#ifdef TASK_OUTPUT
sprintf(tmp
,"X[%06d]",act
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
, tmp
);
#endif
if (l
->act_type
== PAR_ACT_MEAN
) {
next_act
= act_1
+ rand() % act_2
- act_2
/2;
kern_gettime
(&next_time
);
ADDUSEC2TIMESPEC
(next_act
,&next_time
);
kern_event_post
(&next_time
,(void *)((void *)task_activate
),(void *)exec_shadow
);
}
if (l
->act_type
== PAR_ACT_GAUSS
) {
}
if (l
->act_type
== PAR_ACT_GAUSS_MAX
) {
}
if (l
->exec_type
== PAR_EXEC_CONST
)
exec_cycles
= (long long)(exec_1
) * CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_MEAN
)
exec_cycles
= (long long)(exec_1
+ rand() % exec_2
- exec_2
/2)
* CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_GAUSS
)
exec_cycles
= 0;
if (l
->exec_type
== PAR_EXEC_GAUSS_MAX
)
exec_cycles
= 0;
if (l
->crit_type
== PAR_CRIT
) {
crit_start
= crit_1
+ rand() % crit_2
- crit_2
/2;
crit_len
= crit_3
+ rand() % crit_4
- crit_4
/2;
crit_start_cycles
= (long long)(crit_start
) * CALIBRATION_DELTA
/ cal_cycles
;
crit_len_cycles
= (long long)(crit_len
) * CALIBRATION_DELTA
/ cal_cycles
;
exec_cycles
-= crit_start_cycles
+ crit_len_cycles
;
if (exec_cycles
< 0) {
cprintf
("Error: exec_cycles < 0\n");
sys_end
();
}
}
if (l
->crit_type
== PAR_NO_CRIT
)
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
else {
for (i
=0;i
<crit_start_cycles
;i
++) kern_gettime
(NULL
);
#ifdef TASK_OUTPUT
sprintf(tmp
,"B[%02d][%02d]",exec_shadow
,l
->resource
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, RED
, tmp
);
#endif
mutex_lock
(&mux_table
[l
->resource
]);
for (i
=0;i
<crit_len_cycles
;i
++) kern_gettime
(NULL
);
mutex_unlock
(&mux_table
[l
->resource
]);
#ifdef TASK_OUTPUT
sprintf(tmp
,"X[%06d]",act
);
printf_xy
((exec_shadow
% 5) * 9 + 34, exec_shadow
/ 5 + 5, GREEN
, tmp
);
#endif
for (i
=0;i
<exec_cycles
;i
++) kern_gettime
(NULL
);
}
}
return NULL
;
}
/* Delay Calibration */
int calibrate_cycle
()
{
long long i
;
struct timespec start
,end
,diff
;
kern_cli
();
kern_gettime
(&start
);
for (i
=0;i
<CALIBRATION_DELTA
;i
++) kern_gettime
(NULL
);
kern_gettime
(&end
);
kern_sti
();
SUBTIMESPEC
(&end
,&start
,&diff
);
cal_cycles
= TIMESPEC2USEC
(&diff
);
cprintf
("Calibration usec/[%d cycles] = %d\n",CALIBRATION_DELTA
,cal_cycles
);
return 0;
}
/* Mutex create */
void loader_mutex_create
(struct loader_task
*start_loader_task
)
{
struct loader_task
*current
= start_loader_task
;
int i
,res
= 0;
PI_mutexattr_t a
;
int init_array
[MAX_MUTEX
];
PI_mutexattr_default
(a
);
for (i
= 0;i
< MAX_MUTEX
;i
++) init_array
[i
] = 0;
while (current
!= NULL
) {
if (current
->crit_type
== PAR_CRIT
) {
if (init_array
[current
->resource
] == 0) {
mutex_init
(&mux_table
[current
->resource
],&a
);
init_array
[current
->resource
] = 1;
res
++;
}
}
current
= current
->next
;
}
cprintf
("Created %d mutex\n",res
);
}
/* Task create */
void loader_task_create
(struct loader_task
*start_loader_task
)
{
struct loader_task
*current
= start_loader_task
;
char tmp
[30];
int i
, total_task
;
int total_group
= 0;
PID p
;
total_task
= 0;
while (current
!= NULL
) {
total_group
++;
current
->group
= total_group
;
current
->bandwidth
= 0;
for (i
=0; i
< current
->number
; i
++) {
if (current
->task_type
== PAR_TASK_NRT
) {
NRT_TASK_MODEL nrt
;
nrt_task_default_model
(nrt
);
nrt_task_def_save_arrivals
(nrt
);
nrt_task_def_arg
(nrt
,(void *)(current
));
nrt_task_def_ctrl_jet
(nrt
);
nrt_task_def_level
(nrt
,current
->task_level
);
nrt_task_def_group
(nrt
,total_group
);
nrt_task_def_usemath
(nrt
);
sprintf(tmp
,"NRT %d:%d",current
->group
,i
);
p
= task_create
(tmp
,nrt_test_task
,&nrt
,NULL
);
if (p
== NIL
) {
cprintf
("Error nrt task creating\n");
sys_end
();
}
total_task
++;
}
if (current
->task_type
== PAR_TASK_BACK
) {
NRT_TASK_MODEL nrt
;
nrt_task_default_model
(nrt
);
nrt_task_def_save_arrivals
(nrt
);
nrt_task_def_arg
(nrt
,(void *)(current
));
nrt_task_def_ctrl_jet
(nrt
);
nrt_task_def_level
(nrt
,current
->task_level
);
nrt_task_def_group
(nrt
,total_group
);
nrt_task_def_usemath
(nrt
);
sprintf(tmp
,"BACK %d:%d",current
->group
,i
);
p
= task_create
(tmp
,back_task
,&nrt
,NULL
);
if (p
== NIL
) {
cprintf
("Error back task creating\n");
sys_end
();
}
total_task
++;
}
if (current
->task_type
== PAR_TASK_HARD
) {
HARD_TASK_MODEL ht
;
hard_task_default_model
(ht
);
hard_task_def_arg
(ht
,(void *)(current
));
hard_task_def_wcet
(ht
,TIMESPEC2USEC
(¤t
->wcet
));
hard_task_def_ctrl_jet
(ht
);
hard_task_def_level
(ht
,current
->task_level
);
hard_task_def_group
(ht
,total_group
);
hard_task_def_usemath
(ht
);
if (current
->act_type
!= PAR_ACT_PERIODIC
) {
hard_task_def_mit
(ht
,TIMESPEC2USEC
(¤t
->deadline
));
current
->bandwidth
+= MAX_BANDWIDTH
/ TIMESPEC2USEC
(¤t
->deadline
)
* TIMESPEC2USEC
(¤t
->wcet
);
hard_task_def_aperiodic
(ht
);
} else {
hard_task_def_mit
(ht
,TIMESPEC2USEC
(¤t
->act_par_2
));
current
->bandwidth
+= MAX_BANDWIDTH
/ TIMESPEC2USEC
(¤t
->act_par_2
)
* TIMESPEC2USEC
(¤t
->wcet
);
}
sprintf(tmp
,"HARD %d:%d",current
->group
,i
);
p
= task_create
(tmp
,test_task
,&ht
,NULL
);
if (p
== NIL
) {
cprintf
("Error hard task creating\n");
sys_end
();
}
total_task
++;
}
if (current
->task_type
== PAR_TASK_SOFT
) {
SOFT_TASK_MODEL st
;
soft_task_default_model
(st
);
soft_task_def_save_arrivals
(st
);
soft_task_def_arg
(st
,(void *)(current
));
soft_task_def_met
(st
,TIMESPEC2USEC
(¤t
->wcet
));
soft_task_def_ctrl_jet
(st
);
soft_task_def_level
(st
,current
->task_level
);
soft_task_def_group
(st
,total_group
);
soft_task_def_usemath
(st
);
if (current
->act_type
== PAR_ACT_PERIODIC
) {
soft_task_def_period
(st
,TIMESPEC2USEC
(¤t
->act_par_2
));
current
->bandwidth
+= MAX_BANDWIDTH
/ TIMESPEC2USEC
(¤t
->act_par_2
)
* TIMESPEC2USEC
(¤t
->wcet
);
} else if (current
->act_type
!= PAR_ACT_SINGLE
) {
soft_task_def_period
(st
,TIMESPEC2USEC
(¤t
->act_par_2
));
current
->bandwidth
+= MAX_BANDWIDTH
/ TIMESPEC2USEC
(¤t
->act_par_2
)
* TIMESPEC2USEC
(¤t
->wcet
);
soft_task_def_aperiodic
(st
);
} else {
soft_task_def_period
(st
,TIMESPEC2USEC
(¤t
->wcet
)*1000);
current
->bandwidth
+= MAX_BANDWIDTH
/ 1000;
soft_task_def_aperiodic
(st
);
}
sprintf(tmp
,"SOFT %d:%d",current
->group
,i
);
p
= task_create
(tmp
,test_task
,&st
,NULL
);
if (p
== NIL
) {
cprintf
("Error soft task creating\n");
sys_end
();
}
total_task
++;
}
if (current
->task_type
== PAR_TASK_FSF
) {
if (current
->local_scheduler
== PAR_POSIX
) {
NRT_TASK_MODEL nrt
;
pthread_t j
;
int err
;
nrt_task_default_model
(nrt
);
nrt_task_def_save_arrivals
(nrt
);
nrt_task_def_ctrl_jet
(nrt
);
nrt_task_def_usemath
(nrt
);
err
= fsf_create_thread
(current
->server
,&j
,NULL
,back_task
,(void *)current
,&nrt
);
if (err
) {
cprintf
("Error fsf task creating\n");
sys_end
();
}
}
if (current
->local_scheduler
== PAR_EDF
) {
HARD_TASK_MODEL ht
;
pthread_t j
;
int err
;
hard_task_default_model
(ht
);
hard_task_def_ctrl_jet
(ht
);
hard_task_def_mit
(ht
,TIMESPEC2USEC
(¤t
->deadline
));
hard_task_def_wcet
(ht
,TIMESPEC2USEC
(¤t
->wcet
));
hard_task_def_usemath
(ht
);
err
= fsf_create_thread
(current
->server
,&j
,NULL
,test_task
,(void *)current
,&ht
);
if (err
) {
cprintf
("Error fsf task creating\n");
sys_end
();
}
}
if (current
->local_scheduler
== PAR_RM
) {
HARD_TASK_MODEL ht
;
pthread_t j
;
int err
;
hard_task_default_model
(ht
);
hard_task_def_mit
(ht
,TIMESPEC2USEC
(¤t
->deadline
));
hard_task_def_wcet
(ht
,TIMESPEC2USEC
(¤t
->wcet
));
hard_task_def_ctrl_jet
(ht
);
hard_task_def_usemath
(ht
);
err
= fsf_create_thread
(current
->server
,&j
,NULL
,test_task
,(void *)current
,&ht
);
if (err
) {
cprintf
("Error fsf task creating\n");
sys_end
();
}
}
total_task
++;
}
}
cprintf
("Task group %d created. Worst case BW = %d.%d \n",
current
->group
,(int)( (long long)current
->bandwidth
* 100 / MAX_BANDWIDTH
),
(int)( (long long)current
->bandwidth
* 100000 / MAX_BANDWIDTH
% 1000));
current
= current
->next
;
}
cprintf
("Created %d tasks\n",total_task
);
}
/* Set the first extivation events */
void loader_first_execution
(struct loader_task
*start_loader_task
)
{
struct loader_task
*current
= start_loader_task
;
struct timespec start_time
;
while (current
!= NULL
) {
if (current
->task_type
!= PAR_TASK_FSF
) {
ADDTIMESPEC
(&zero_time
,¤t
->act_par_1
,&start_time
);
kern_event_post
(&start_time
, (void *)((void *)group_activate
), (void *)(current
->group
));
}
current
= current
->next
;
}
}
void fsfinit
(void);
int main
()
{
struct loader_task
*start_loader_task
= NULL
;
struct timespec total
;
struct timespec end_time
;
line_reader
(start_file
, end_file
, &total
, &start_loader_task
);
srand(kern_gettime
(NULL
));
calibrate_cycle
();
fsfinit
();
loader_mutex_create
(start_loader_task
);
loader_task_create
(start_loader_task
);
kern_gettime
(&zero_time
);
loader_first_execution
(start_loader_task
);
ADDTIMESPEC
(&zero_time
,&total
,&end_time
);
kern_event_post
(&end_time
,(void *)((void *)(sys_end
)),NULL
);
return 0;
}