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