1 /* This file contains the main program of the SCHED scheduler. It will sit idle 2 * until asked, by PM, to take over scheduling a particular process. 3 */ 4 5 /* The _MAIN def indicates that we want the schedproc structs to be created 6 * here. Used from within schedproc.h */ 7 #define _MAIN 8 9 #include "sched.h" 10 #include "schedproc.h" 11 12 /* Declare some local functions. */ 13 static void reply(endpoint_t whom, message *m_ptr); 14 static void sef_local_startup(void); 15 16 struct machine machine; /* machine info */ 17 18 /*===========================================================================* 19 * main * 20 *===========================================================================*/ 21 int main(void) 22 { 23 /* Main routine of the scheduler. */ 24 message m_in; /* the incoming message itself is kept here. */ 25 int call_nr; /* system call number */ 26 int who_e; /* caller's endpoint */ 27 int result; /* result to system call */ 28 int rv; 29 int s; 30 31 /* SEF local startup. */ 32 sef_local_startup(); 33 34 if (OK != (s=sys_getmachine(&machine))) 35 panic("couldn't get machine info: %d", s); 36 /* Initialize scheduling timers, used for running balance_queues */ 37 init_scheduling(); 38 39 /* This is SCHED's main loop - get work and do it, forever and forever. */ 40 while (TRUE) { 41 int ipc_status; 42 43 /* Wait for the next message and extract useful information from it. */ 44 if (sef_receive_status(ANY, &m_in, &ipc_status) != OK) 45 panic("SCHED sef_receive error"); 46 who_e = m_in.m_source; /* who sent the message */ 47 call_nr = m_in.m_type; /* system call number */ 48 49 /* Check for system notifications first. Special cases. */ 50 if (is_ipc_notify(ipc_status)) { 51 switch(who_e) { 52 case CLOCK: 53 expire_timers(m_in.m_notify.timestamp); 54 continue; /* don't reply */ 55 default : 56 result = ENOSYS; 57 } 58 59 goto sendreply; 60 } 61 62 switch(call_nr) { 63 case SCHEDULING_INHERIT: 64 case SCHEDULING_START: 65 result = do_start_scheduling(&m_in); 66 break; 67 case SCHEDULING_STOP: 68 result = do_stop_scheduling(&m_in); 69 break; 70 case SCHEDULING_SET_NICE: 71 result = do_nice(&m_in); 72 break; 73 case SCHEDULING_NO_QUANTUM: 74 /* This message was sent from the kernel, don't reply */ 75 if (IPC_STATUS_FLAGS_TEST(ipc_status, 76 IPC_FLG_MSG_FROM_KERNEL)) { 77 if ((rv = do_noquantum(&m_in)) != (OK)) { 78 printf("SCHED: Warning, do_noquantum " 79 "failed with %d\n", rv); 80 } 81 continue; /* Don't reply */ 82 } 83 else { 84 printf("SCHED: process %d faked " 85 "SCHEDULING_NO_QUANTUM message!\n", 86 who_e); 87 result = EPERM; 88 } 89 break; 90 default: 91 result = no_sys(who_e, call_nr); 92 } 93 94 sendreply: 95 /* Send reply. */ 96 if (result != SUSPEND) { 97 m_in.m_type = result; /* build reply message */ 98 reply(who_e, &m_in); /* send it away */ 99 } 100 } 101 return(OK); 102 } 103 104 /*===========================================================================* 105 * reply * 106 *===========================================================================*/ 107 static void reply(endpoint_t who_e, message *m_ptr) 108 { 109 int s = ipc_send(who_e, m_ptr); /* send the message */ 110 if (OK != s) 111 printf("SCHED: unable to send reply to %d: %d\n", who_e, s); 112 } 113 114 /*===========================================================================* 115 * sef_local_startup * 116 *===========================================================================*/ 117 static void sef_local_startup(void) 118 { 119 /* No init callbacks for now. */ 120 /* No live update support for now. */ 121 /* No signal callbacks for now. */ 122 123 /* Let SEF perform startup. */ 124 sef_startup(); 125 } 126