Rev 1624 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "kernel/kern.h"
#include "fsf_contract.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
#include "pthread.h"
#include "drivers/keyb.h"
#include "drivers/glib.h"
#define TEST_PERIOD 50000
mutex_t mux
;
void program_key_end
(KEY_EVT
*k
)
{
sys_end
();
}
void print_timer
(int x
, int y
)
{
long nsec
,sec
,min
,hrs
,day
;
struct timespec actual_timer
;
char tmp
[100];
sys_gettime
(&actual_timer
);
nsec
= actual_timer.
tv_nsec;
sec
= actual_timer.
tv_sec;
min
= sec
/ 60;
sec
%= 60;
hrs
= min
/ 60;
min
%= 60;
day
= hrs
/ 24;
hrs
%= 24;
sprintf(tmp
,"Time: %2ld d %2ld h %2ld m %2ld s %12ld ns",day
,hrs
,min
,sec
,(long)nsec
);
//mutex_lock(&mux);
grx_text
(tmp
,x
,y
,rgb16
(255,255,255),0);
//mutex_unlock(&mux);
}
#define LOAD_VARIATION 10
#define MAX_V_QOS 30
#define MIN_V_QOS 2
void *test_task_variable
(void *arg
) {
char tmp
[100];
long long i
;
int task_qos
;
int var_load
, rd_per
;
TIME exectime
;
task_qos
= 7;
var_load
= 5;
rd_per
= 0;
while(1) {
print_timer
(307,10+30*exec_shadow
);
sprintf(tmp
,"Test Thread V QOS = %5d PID = %3d VLOAD = %3d",task_qos
,exec_shadow
,var_load
);
//mutex_lock(&mux);
grx_text
(tmp
,307,20+30*exec_shadow
,rgb16
(255,255,255),0);
//mutex_unlock(&mux);
jet_gettable
(exec_shadow
, &exectime
, 1);
sprintf(tmp
,"Thread Exec Timer = %10d us",(int)exectime
);
grx_text
(tmp
,307,30+30*exec_shadow
,rgb16
(255,255,255),0);
if (rd_per
> LOAD_VARIATION
) {
var_load
+= rand()%3-1;
if (var_load
> 20) var_load
= 20;
if (var_load
< 0) var_load
= 0;
rd_per
= 0;
} else {
rd_per
++;
}
for(i
= 0; i
< 10000*(task_qos
+var_load
); i
++);
}
return NULL
;
}
#define MAX_C_QOS 30
#define MIN_C_QOS 2
void *test_task_constant
(void *arg
) {
char tmp
[100];
long long i
;
int task_qos
;
task_qos
= 7;
while(1) {
print_timer
(307,10+20*exec_shadow
);
sprintf(tmp
,"Test Task C QOS = %5d PID = %3d",task_qos
,exec_shadow
);
//mutex_lock(&mux);
grx_text
(tmp
,307,20+20*exec_shadow
,rgb16
(255,255,255),0);
//mutex_unlock(&mux);
for(i
= 0; i
< 10000*task_qos
; i
++);
}
return NULL
;
}
void draw_box
(int x1
, int y1
, int x2
, int y2
)
{
grx_rect
(x1
,y1
,x2
,y2
,rgb16
(160,160,160));
grx_rect
(x1
+2,y1
+2,x2
-2,y2
-2,rgb16
(210,210,210));
}
void layout_screen
()
{
draw_box
(0,0,300,500);
grx_text
("Application Task List",5,5,rgb16
(255,255,255),0);
draw_box
(303,0,799,500);
grx_text
("Task Output",305,5,rgb16
(255,255,255),0);
draw_box
(0,503,799,599);
grx_line
(140,505,140,597,rgb16
(255,255,255));
grx_line
(140,583,797,583,rgb16
(255,255,255));
grx_text
("Application Statistics",142,507,rgb16
(255,255,255),0);
}
void program_end
()
{
grx_close
();
}
void *mpeg2decoder
(void *arg
);
void add_posixstar_thread
(fsf_server_id_t server
)
{
NRT_TASK_MODEL nrt
;
pthread_t j
= -1;
nrt_task_default_model
(nrt
);
fsf_create_thread
(server
, &j
, NULL
, test_task_variable
, NULL
, &nrt
);
}
void add_edfstar_thread
(fsf_server_id_t server
)
{
pthread_t j
= -1;
HARD_TASK_MODEL ht
;
hard_task_default_model
(ht
);
hard_task_def_mit
(ht
,100000);
hard_task_def_wcet
(ht
,90000);
fsf_create_thread
(server
, &j
, NULL
, mpeg2decoder
, NULL
, &ht
);
}
int main
(int argc
, char **argv
)
{
char ch
;
int err
;
KEY_EVT k
;
PI_mutexattr_t a
;
struct timespec period1
= {0,10000000};
struct timespec period2
= {0,10000000};
struct timespec budget1
= {0,4000000};
struct timespec budget2
= {0,4000000};
fsf_server_id_t server1
, server2
;
fsf_contract_parameters_t contract1
, contract2
;
sys_atrunlevel
(program_end
, NULL
, RUNLEVEL_BEFORE_EXIT
);
k.
flag = ALTL_BIT
;
k.
scan = KEY_C
;
k.
ascii = 'c';
keyb_hook
(k
,program_key_end
);
srand(sys_gettime
(NULL
));
// graphic card Initialization
if (grx_init
() < 1) {
sys_end
();
}
if (grx_open
(800, 600, 16) < 0) {
cprintf
("GRX Err\n");
sys_end
();
}
layout_screen
();
PI_mutexattr_default
(a
);
mutex_init
(&mux
,&a
);
fsf_initialize_contract
(&contract1
);
fsf_set_contract_basic_parameters
(&contract1
,&budget1
,&period1
,NULL
,NULL
,FSF_DEFAULT_WORKLOAD
);
fsf_initialize_contract
(&contract2
);
fsf_set_contract_basic_parameters
(&contract2
,&budget2
,&period2
,NULL
,NULL
,FSF_DEFAULT_WORKLOAD
);
fsf_set_local_scheduler_parameter
(&contract2
, FSF_SCHEDULER_EDF
);
err
= fsf_negotiate_contract
(&contract1
,&server1
);
if (err
) cprintf
("(FSF ERROR %d)",err
);
err
= fsf_negotiate_contract
(&contract2
,&server2
);
if (err
) cprintf
("(FSF ERROR %d)",err
);
ch
= keyb_getch
(BLOCK
);
while(ch
!= ESC
) {
switch (ch
) {
case '1':
add_posixstar_thread
(server1
);
break;
case '2':
add_edfstar_thread
(server2
);
break;
case '3':
break;
case '4':
break;
case '5':
break;
}
ch
= keyb_getch
(BLOCK
);
}
sys_end
();
return 0;
}