Cristiano Giuffrida 3f82ac6a4e services: Selectively enable stateful restart.
Change-Id: Ibf6afa3041013ca714e28b673abb1329cd72d2d5
2015-09-17 13:36:01 +00:00

138 lines
3.8 KiB
C

/* This file contains the main program of the SCHED scheduler. It will sit idle
* until asked, by PM, to take over scheduling a particular process.
*/
/* The _MAIN def indicates that we want the schedproc structs to be created
* here. Used from within schedproc.h */
#define _MAIN
#include "sched.h"
#include "schedproc.h"
/* Declare some local functions. */
static void reply(endpoint_t whom, message *m_ptr);
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
struct machine machine; /* machine info */
/*===========================================================================*
* main *
*===========================================================================*/
int main(void)
{
/* Main routine of the scheduler. */
message m_in; /* the incoming message itself is kept here. */
int call_nr; /* system call number */
int who_e; /* caller's endpoint */
int result; /* result to system call */
int rv;
/* SEF local startup. */
sef_local_startup();
/* This is SCHED's main loop - get work and do it, forever and forever. */
while (TRUE) {
int ipc_status;
/* Wait for the next message and extract useful information from it. */
if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
panic("SCHED sef_receive error");
who_e = m_in.m_source; /* who sent the message */
call_nr = m_in.m_type; /* system call number */
/* Check for system notifications first. Special cases. */
if (is_ipc_notify(ipc_status)) {
switch(who_e) {
case CLOCK:
balance_queues();
break;
default :
break;
}
continue; /* Don't reply. */
}
switch(call_nr) {
case SCHEDULING_INHERIT:
case SCHEDULING_START:
result = do_start_scheduling(&m_in);
break;
case SCHEDULING_STOP:
result = do_stop_scheduling(&m_in);
break;
case SCHEDULING_SET_NICE:
result = do_nice(&m_in);
break;
case SCHEDULING_NO_QUANTUM:
/* This message was sent from the kernel, don't reply */
if (IPC_STATUS_FLAGS_TEST(ipc_status,
IPC_FLG_MSG_FROM_KERNEL)) {
if ((rv = do_noquantum(&m_in)) != (OK)) {
printf("SCHED: Warning, do_noquantum "
"failed with %d\n", rv);
}
continue; /* Don't reply */
}
else {
printf("SCHED: process %d faked "
"SCHEDULING_NO_QUANTUM message!\n",
who_e);
result = EPERM;
}
break;
default:
result = no_sys(who_e, call_nr);
}
/* Send reply. */
if (result != SUSPEND) {
m_in.m_type = result; /* build reply message */
reply(who_e, &m_in); /* send it away */
}
}
return(OK);
}
/*===========================================================================*
* reply *
*===========================================================================*/
static void reply(endpoint_t who_e, message *m_ptr)
{
int s = ipc_send(who_e, m_ptr); /* send the message */
if (OK != s)
printf("SCHED: unable to send reply to %d: %d\n", who_e, s);
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup(void)
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_restart(SEF_CB_INIT_RESTART_STATEFUL);
/* No signal callbacks for now. */
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
int s;
if (OK != (s=sys_getmachine(&machine)))
panic("couldn't get machine info: %d", s);
/* Initialize scheduling timers, used for running balance_queues */
init_scheduling();
return(OK);
}