xref: /minix/minix/servers/sched/main.c (revision 83133719)
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