/*
* 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 "fsf_server.h"
#include "stdlib.h"
#include "unistd.h"
#include "string.h"
#include "pthread.h"
#include "drivers/keyb.h"
#include "drivers/glib.h"
/*Init Server Parameters */
#define SERVER_I_PERIOD 50000
#define SERVER_I_BUDGET 10000
#define SERVER_P_PERIOD 50000
#define SERVER_P_BUDGET 10000
#define SERVER_B_PERIOD 50000
#define SERVER_B_BUDGET 10000
struct timespec server_I_period
= {0,SERVER_I_PERIOD
*1000};
struct timespec server_I_budget
= {0,SERVER_I_BUDGET
*1000};
struct timespec server_P_period
= {0,SERVER_P_PERIOD
*1000};
struct timespec server_P_budget
= {0,SERVER_P_BUDGET
*1000};
struct timespec server_B_period
= {0,SERVER_B_PERIOD
*1000};
struct timespec server_B_budget
= {0,SERVER_B_BUDGET
*1000};
fsf_server_id_t server_I
, server_P
, server_B
;
fsf_contract_parameters_t contract_I
, contract_P
, contract_B
;
/* Decoder PID */
pthread_t pI
,pP
,pB
;
#define FRAME_I 0
#define FRAME_P 1
#define FRAME_B 2
struct decoder_arg
{
int frame_number
;
int frame_type
;
int fx
,fy
,fd
;
void *input_buffer_newdata
;
void *input_buffer_pastframe
;
void *output_buffer_newframe
;
int server_id
;
};
typedef struct decoder_arg
*decoder_arg_ptr
;
#define MAX_DECODER_NUMBER 10
/* Table of pointer to decoder_ard struct */
decoder_arg_ptr decoder_arg_table
[MAX_DECODER_NUMBER
];
/* Decoder TASK */
TASK decoder
(void *arg
)
{
decoder_arg_ptr darg
= (decoder_arg_ptr
)(arg
);
int i
,Q
,R
;
struct timespec current
;
while(1) {
cprintf
("Decoder Start %d Frame %d\n",exec_shadow
,darg
->frame_number
);
for (i
=0;i
<100;i
++) {
if (MPEGSTAR_is_frame_skipped
(darg
->server_id
)) {
kern_printf
("Skipping this frame\n");
break;
}
kern_gettime
(¤t
);
}
Q
= MPEGSTAR_get_remain_capacity
(darg
->server_id
);
R
= MPEGSTAR_get_last_reclaiming
(darg
->server_id
);
printf_xy
(55,10+exec_shadow
,WHITE
,"[S%02d:Q%06d:R%06d]",darg
->server_id
,Q
,R
);
cprintf
("Decoder End %d\n",exec_shadow
);
task_endcycle
();
}
return NULL
;
}
int init_mpeg_server
() {
int err
;
HARD_TASK_MODEL ht
;
fsf_initialize_contract
(&contract_I
);
fsf_set_contract_basic_parameters
(&contract_I
,&server_I_budget
,&server_I_period
,NULL
,NULL
,FSF_DEFAULT_WORKLOAD
);
fsf_set_local_scheduler_parameter
(&contract_I
, FSF_SCHEDULER_MPEG
);
fsf_initialize_contract
(&contract_P
);
fsf_set_contract_basic_parameters
(&contract_P
,&server_P_budget
,&server_P_period
,NULL
,NULL
,FSF_DEFAULT_WORKLOAD
);
fsf_set_local_scheduler_parameter
(&contract_P
, FSF_SCHEDULER_MPEG
);
fsf_initialize_contract
(&contract_B
);
fsf_set_contract_basic_parameters
(&contract_B
,&server_B_budget
,&server_B_period
,NULL
,NULL
,FSF_DEFAULT_WORKLOAD
);
fsf_set_local_scheduler_parameter
(&contract_B
, FSF_SCHEDULER_MPEG
);
err
= fsf_negotiate_contract
(&contract_I
,&server_I
);
if (err
) cprintf
("(FSF ERROR %d)",err
);
err
= fsf_negotiate_contract
(&contract_P
,&server_P
);
if (err
) cprintf
("(FSF ERROR %d)",err
);
err
= fsf_negotiate_contract
(&contract_B
,&server_B
);
if (err
) cprintf
("(FSF ERROR %d)",err
);
hard_task_default_model
(ht
);
decoder_arg_table
[server_I
] = (decoder_arg_ptr
)malloc(sizeof(struct decoder_arg
));
decoder_arg_table
[server_I
]->server_id
= server_I
;
fsf_create_thread
(server_I
, &pI
, NULL
, decoder
, decoder_arg_table
[server_I
], &ht
);
cprintf
("Decoder I PID %d\n",pI
);
decoder_arg_table
[server_P
] = (decoder_arg_ptr
)malloc(sizeof(struct decoder_arg
));
decoder_arg_table
[server_P
]->server_id
= server_P
;
fsf_create_thread
(server_P
, &pP
, NULL
, decoder
, decoder_arg_table
[server_P
], &ht
);
cprintf
("Decoder P PID %d\n",pP
);
decoder_arg_table
[server_B
] = (decoder_arg_ptr
)malloc(sizeof(struct decoder_arg
));
decoder_arg_table
[server_B
]->server_id
= server_B
;
fsf_create_thread
(server_B
, &pB
, NULL
, decoder
, decoder_arg_table
[server_B
], &ht
);
cprintf
("Decoder B PID %d\n",pB
);
return 0;
}
/* Decoder Manager TASK */
TASK decoder_manager
(void *arg
) {
TIME T
,Q
;
T
= 50000;
Q
= 10000;
MPEGSTAR_rescale
(server_I
,Q
,T
);
decoder_arg_table
[server_I
]->frame_number
= 0;
decoder_arg_table
[server_I
]->frame_type
= FRAME_I
;
task_activate
(pI
);
T
= 150000;
Q
= 10000;
MPEGSTAR_rescale
(server_P
,Q
,T
);
decoder_arg_table
[server_P
]->frame_number
= 2;
decoder_arg_table
[server_P
]->frame_type
= FRAME_P
;
task_activate
(pP
);
T
= 100000;
Q
= 10000;
MPEGSTAR_rescale
(server_B
,Q
,T
);
decoder_arg_table
[server_B
]->frame_number
= 1;
decoder_arg_table
[server_B
]->frame_type
= FRAME_B
;
task_activate
(pB
);
return 0;
}
int main
() {
HARD_TASK_MODEL ht_manager
;
PID dm
;
init_mpeg_server
();
hard_task_default_model
(ht_manager
);
hard_task_def_mit
(ht_manager
,10000);
hard_task_def_wcet
(ht_manager
,5000);
hard_task_def_arg
(ht_manager
,NULL
);
dm
= task_create
("Manager", decoder_manager
, &ht_manager
, NULL
);
if (dm
== NIL
) {
cprintf
("Error creating decoder manager\n");
sys_end
();
}
cprintf
("Control-C to exit\n");
task_activate
(dm
);
while(1);
return 0;
}