Rev 1205 |
Rev 1207 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#include <kernel/kern.h>
#include "parser.h"
#include "dosread.h"
/* Memory pointers on loaded file */
extern void *start
;
extern void *end
;
/* Calibration Loops */
#define CALIBRATION_DELTA 1000000
/* Mutex number */
#define MAX_MUTEX 10
/* Activate task output */
#define TASK_OUTPUT
struct timespec zero_time
;
int cal_cycles
= 0;
int cal_rit_start
= 0;
int cal_rit_calc_const
= 0;
int cal_rit_calc_mean
= 0;
int cal_rit_calc_gauss
= 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
;
static int act
= 0;
struct loader_task
*l
= (struct loader_task
*)(arg
);
act
++;
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
% 20 + 60, exec_shadow
/ 20, GREEN
, "R");
#endif
if (l
->exec_type
== PAR_EXEC_CONST
)
exec_cycles
= (long long)(exec_1
- cal_rit_start
- cal_rit_calc_const
)
* CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_MEAN
)
exec_cycles
= (long long)(exec_1
- cal_rit_start
- cal_rit_calc_mean
+ 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
++);
else {
for (i
=0;i
<crit_start_cycles
;i
++);
#ifdef TASK_OUTPUT
printf_xy
(exec_shadow
% 20 + 59, exec_shadow
/ 20, RED
,"B");
#endif
mutex_lock
(&mux_table
[l
->resource
]);
for (i
=0;i
<crit_len_cycles
;i
++);
mutex_unlock
(&mux_table
[l
->resource
]);
#ifdef TASK_OUTPUT
printf_xy
(exec_shadow
% 20 + 59, exec_shadow
/ 20, GREEN
,"R");
#endif
for (i
=0;i
<exec_cycles
;i
++);
}
#ifdef TASK_OUTPUT
printf_xy
(exec_shadow
% 20 + 60, exec_shadow
/ 20, WHITE
, "E");
#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
;
static int act
=0;
int extra_rit
, k
;
struct loader_task
*l
= (struct loader_task
*)(arg
);
act
++;
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
);
extra_rit
= cal_rit_start
;
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
);
}
k
= 0;
while(1) {
task_testcancel
();
#ifdef TASK_OUTPUT
k
++;
if (k
> 15) k
= 1;
printf_xy
(exec_shadow
% 20 + 59, exec_shadow
/ 20, k
,"X");
#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
- extra_rit
- cal_rit_calc_const
)
* CALIBRATION_DELTA
/ cal_cycles
;
if (l
->exec_type
== PAR_EXEC_MEAN
)
exec_cycles
= (long long)(exec_1
- extra_rit
- cal_rit_calc_mean
+ 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
();
}
}
extra_rit
= 0;
if (l
->crit_type
== PAR_NO_CRIT
)
for (i
=0;i
<exec_cycles
;i
++);
else {
for (i
=0;i
<crit_start_cycles
;i
++);
#ifdef TASK_OUTPUT
printf_xy
(exec_shadow
% 20 + 59, exec_shadow
/ 20, k
,"B");
#endif
mutex_lock
(&mux_table
[l
->resource
]);
for (i
=0;i
<crit_len_cycles
;i
++);
mutex_unlock
(&mux_table
[l
->resource
]);
#ifdef TASK_OUTPUT
printf_xy
(exec_shadow
% 20 + 59, exec_shadow
/ 20, k
,"X");
#endif
for (i
=0;i
<exec_cycles
;i
++);
}
task_endcycle
();
}
return NULL
;
}
/* Delay Calibration */
int calibrate_cycle
()
{
long long i
;
struct timespec start
,end
,diff
;
int temp
= 1234567;
int temp_1
= 1234567;
int temp_2
= 1234567;
kern_cli
();
kern_gettime
(&start
);
for (i
=0;i
<CALIBRATION_DELTA
;i
++);
kern_gettime
(&end
);
kern_sti
();
SUBTIMESPEC
(&end
,&start
,&diff
);
cal_cycles
= TIMESPEC2USEC
(&diff
);
cprintf
("Calibration usec/[%d cycles] = %d\n",CALIBRATION_DELTA
,cal_cycles
);
kern_cli
();
kern_gettime
(&start
);
temp
= (long long)(temp_1
) * CALIBRATION_DELTA
/ cal_cycles
;
kern_gettime
(&end
);
kern_sti
();
SUBTIMESPEC
(&end
,&start
,&diff
);
cal_rit_calc_const
= TIMESPEC2USEC
(&diff
);
kern_cli
();
kern_gettime
(&start
);
temp
= (long long)(temp_1
+ rand() % temp_2
- temp_2
/2) * CALIBRATION_DELTA
/ cal_cycles
;
kern_gettime
(&end
);
kern_sti
();
SUBTIMESPEC
(&end
,&start
,&diff
);
cal_rit_calc_mean
= TIMESPEC2USEC
(&diff
);
kern_cli
();
kern_gettime
(&start
);
temp
= TIMESPEC2USEC
(&start
);
kern_gettime
(&end
);
kern_sti
();
SUBTIMESPEC
(&end
,&start
,&diff
);
cal_rit_start
= TIMESPEC2USEC
(&diff
) * 6 + cal_rit_calc_const
;
cprintf
("Calibration delay start = %d const = %d mean = %d gauss = %d\n",
cal_rit_start
,cal_rit_calc_const
,cal_rit_calc_mean
,cal_rit_calc_gauss
);
return 0;
}
/* Mutex create */
void loader_mutex_create
(struct loader_task
*start_loader_task
)
{
struct loader_task
*current
= start_loader_task
;
int res
= 0;
PI_mutexattr_t a
;
PI_mutexattr_default
(a
);
while (current
!= NULL
) {
if (current
->crit_type
== PAR_CRIT
) {
mutex_init
(&mux_table
[current
->resource
],&a
);
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
);
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_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
);
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
);
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
++;
}
}
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
) {
ADDTIMESPEC
(&zero_time
,¤t
->act_par_1
,&start_time
);
kern_event_post
(&start_time
, (void *)((void *)group_activate
), (void *)(current
->group
));
current
= current
->next
;
}
}
int main
()
{
struct loader_task
*start_loader_task
= NULL
;
struct timespec total
;
struct timespec end_time
;
line_reader
(start
, end
, &total
, &start_loader_task
);
srand(kern_gettime
(NULL
));
calibrate_cycle
();
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;
}