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 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 16 17 struct machine machine; /* machine info */ 18 19 /*===========================================================================* 20 * main * 21 *===========================================================================*/ 22 int main(void) 23 { 24 /* Main routine of the scheduler. */ 25 message m_in; /* the incoming message itself is kept here. */ 26 int call_nr; /* system call number */ 27 int who_e; /* caller's endpoint */ 28 int result; /* result to system call */ 29 int rv; 30 31 /* SEF local startup. */ 32 sef_local_startup(); 33 34 /* This is SCHED's main loop - get work and do it, forever and forever. */ 35 while (TRUE) { 36 int ipc_status; 37 38 /* Wait for the next message and extract useful information from it. */ 39 if (sef_receive_status(ANY, &m_in, &ipc_status) != OK) 40 panic("SCHED sef_receive error"); 41 who_e = m_in.m_source; /* who sent the message */ 42 call_nr = m_in.m_type; /* system call number */ 43 44 /* Check for system notifications first. Special cases. */ 45 if (is_ipc_notify(ipc_status)) { 46 switch(who_e) { 47 case CLOCK: 48 balance_queues(); 49 break; 50 default : 51 break; 52 } 53 54 continue; /* Don't reply. */ 55 } 56 57 switch(call_nr) { 58 case SCHEDULING_INHERIT: 59 case SCHEDULING_START: 60 result = do_start_scheduling(&m_in); 61 break; 62 case SCHEDULING_STOP: 63 result = do_stop_scheduling(&m_in); 64 break; 65 case SCHEDULING_SET_NICE: 66 result = do_nice(&m_in); 67 break; 68 case SCHEDULING_NO_QUANTUM: 69 /* This message was sent from the kernel, don't reply */ 70 if (IPC_STATUS_FLAGS_TEST(ipc_status, 71 IPC_FLG_MSG_FROM_KERNEL)) { 72 if ((rv = do_noquantum(&m_in)) != (OK)) { 73 printf("SCHED: Warning, do_noquantum " 74 "failed with %d\n", rv); 75 } 76 continue; /* Don't reply */ 77 } 78 else { 79 printf("SCHED: process %d faked " 80 "SCHEDULING_NO_QUANTUM message!\n", 81 who_e); 82 result = EPERM; 83 } 84 break; 85 default: 86 result = no_sys(who_e, call_nr); 87 } 88 89 /* Send reply. */ 90 if (result != SUSPEND) { 91 m_in.m_type = result; /* build reply message */ 92 reply(who_e, &m_in); /* send it away */ 93 } 94 } 95 return(OK); 96 } 97 98 /*===========================================================================* 99 * reply * 100 *===========================================================================*/ 101 static void reply(endpoint_t who_e, message *m_ptr) 102 { 103 int s = ipc_send(who_e, m_ptr); /* send the message */ 104 if (OK != s) 105 printf("SCHED: unable to send reply to %d: %d\n", who_e, s); 106 } 107 108 /*===========================================================================* 109 * sef_local_startup * 110 *===========================================================================*/ 111 static void sef_local_startup(void) 112 { 113 /* Register init callbacks. */ 114 sef_setcb_init_fresh(sef_cb_init_fresh); 115 sef_setcb_init_restart(SEF_CB_INIT_RESTART_STATEFUL); 116 117 /* No signal callbacks for now. */ 118 119 /* Let SEF perform startup. */ 120 sef_startup(); 121 } 122 123 /*===========================================================================* 124 * sef_cb_init_fresh * 125 *===========================================================================*/ 126 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 127 { 128 int s; 129 130 if (OK != (s=sys_getmachine(&machine))) 131 panic("couldn't get machine info: %d", s); 132 /* Initialize scheduling timers, used for running balance_queues */ 133 init_scheduling(); 134 135 return(OK); 136 } 137 138