- machine information contains the number of cpus and the bsp id - a dummy SMP scheduler which keeps all system processes on BSP and all other process on APs. The scheduler remembers how many processes are assigned to each CPU and always picks the one with the least processes for a new process.
125 lines
3.5 KiB
C
125 lines
3.5 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. */
|
|
FORWARD _PROTOTYPE( void reply, (endpoint_t whom, message *m_ptr) );
|
|
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
|
|
|
|
PUBLIC struct machine machine; /* machine info */
|
|
|
|
/*===========================================================================*
|
|
* main *
|
|
*===========================================================================*/
|
|
PUBLIC 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;
|
|
int s;
|
|
|
|
/* SEF local startup. */
|
|
sef_local_startup();
|
|
|
|
if (OK != (s=sys_getmachine(&machine)))
|
|
panic("couldn't get machine info: %d", s);
|
|
/* Initialize scheduling timers, used for running balance_queues */
|
|
init_scheduling();
|
|
|
|
/* 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:
|
|
expire_timers(m_in.NOTIFY_TIMESTAMP);
|
|
continue; /* don't reply */
|
|
default :
|
|
result = ENOSYS;
|
|
}
|
|
|
|
goto sendreply;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
sendreply:
|
|
/* Send reply. */
|
|
if (result != SUSPEND) {
|
|
m_in.m_type = result; /* build reply message */
|
|
reply(who_e, &m_in); /* send it away */
|
|
}
|
|
}
|
|
return(OK);
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* reply *
|
|
*===========================================================================*/
|
|
PRIVATE void reply(endpoint_t who_e, message *m_ptr)
|
|
{
|
|
int s = 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 *
|
|
*===========================================================================*/
|
|
PRIVATE void sef_local_startup(void)
|
|
{
|
|
/* No init callbacks for now. */
|
|
/* No live update support for now. */
|
|
/* No signal callbacks for now. */
|
|
|
|
/* Let SEF perform startup. */
|
|
sef_startup();
|
|
}
|