Rev 799 | Rev 868 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
//=====================================================================
// FFFFFFIII RRRRR SSTTTTTTT
// FF IIR RR SS
// FF IR SS
// FFFFFF RRRR SSSSST
// FF FI RRR SS
// FF II RRR SS
// FF IIIIIR RS
//
// Basic FSF(FIRST Scheduling Framework) contract management
// S.Ha.R.K. Implementation
//=====================================================================
#include "fsf_contract.h"
#include "fsf_server.h"
extern int fsf_server_level;
//#define FSF_DEBUG
int
fsf_create_synchobject(fsf_synch_object_handle_t *synch_handle)
{
if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
iq_init(&synch_handle->threads, NULL, 0);
synch_handle->events = 0;
return 0;
}
int
fsf_signal_synchobject(fsf_synch_object_handle_t *synch_handle)
{
PID p;
if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
if ((p = iq_getfirst(&synch_handle->threads)) != NIL)
task_activate(p);
else
synch_handle->events++;
return 0;
}
int
fsf_destroy_synchobject(fsf_synch_object_handle_t *synch_handle)
{
if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
while (iq_getfirst(&synch_handle->threads) != NIL);
synch_handle->events = 0;
return 0;
}
int fsf_schedule_next_timed_job
(const struct timespec *at_absolute_time,
struct timespec *next_budget,
struct timespec *next_period,
bool *was_deadline_missed,
bool *was_budget_overran)
{
TIME T,Q,D;
int budget, local_scheduler_level, scheduler_id;
local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
break;
case FSF_SCHEDULER_EDF:
budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
break;
case FSF_SCHEDULER_NONE:
budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
break;
case FSF_SCHEDULER_RM:
budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
break;
default:
budget = -1;
break;
}
if (budget == -1) return FSF_ERR_INVALID_SERVER;
if (next_budget != NULL && next_period != NULL) {
SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
#ifdef FSF_DEBUG
kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
#endif
next_budget->tv_sec = Q / 1000000;
next_budget->tv_nsec = (Q % 1000000) * 1000;
next_period->tv_sec = T / 1000000;
next_period->tv_nsec = (T % 1000000) * 1000;
}
if (was_deadline_missed != NULL)
*was_deadline_missed = false;
if (was_budget_overran != NULL)
*was_budget_overran = false;
if (at_absolute_time != NULL)
kern_event_post(at_absolute_time, (void (*)(void *))task_activate, (void *)(exec_shadow));
#ifdef FSF_DEBUG
if (at_absolute_time != NULL)
kern_printf("(Next act s%d:us%d)",(int)at_absolute_time->tv_sec,(int)at_absolute_time->tv_nsec/1000);
else
kern_printf("(End Cycle %d)",exec_shadow);
#endif
task_endcycle();
return 0;
}
int
fsf_schedule_next_event_triggered_job
(fsf_synch_object_handle_t *synch_handle,
struct timespec *next_budget,
struct timespec *next_period,
bool *was_deadline_missed,
bool *was_budget_overran)
{
TIME T,Q,D;
int budget, local_scheduler_level, scheduler_id;
local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
break;
case FSF_SCHEDULER_EDF:
budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
break;
case FSF_SCHEDULER_RM:
default:
budget = -1;
break;
}
if (budget == -1) return FSF_ERR_INVALID_SERVER;
if (next_budget != NULL && next_period != NULL) {
SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
#ifdef FSF_DEBUG
kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
#endif
next_budget->tv_sec = Q / 1000000;
next_budget->tv_nsec = (Q % 1000000) * 1000;
next_period->tv_sec = T / 1000000;
next_period->tv_nsec = (T % 1000000) * 1000;
}
if (was_deadline_missed != NULL)
*was_deadline_missed = false;
if (was_budget_overran != NULL)
*was_budget_overran = false;
if (synch_handle->events > 0) {
task_activate(exec_shadow);
synch_handle->events--;
} else
iq_insertlast(exec_shadow,&synch_handle->threads);
#ifdef FSF_DEBUG
kern_printf("(Synch_Handle Events %d)",synch_handle->events);
#endif
task_endcycle();
return 0;
}