xref: /minix3/minix/servers/sched/main.c (revision 3f82ac6a4e188419336747098d0d6616cd2f3d3d)
1433d6423SLionel Sambuc /* This file contains the main program of the SCHED scheduler. It will sit idle
2433d6423SLionel Sambuc  * until asked, by PM, to take over scheduling a particular process.
3433d6423SLionel Sambuc  */
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc /* The _MAIN def indicates that we want the schedproc structs to be created
6433d6423SLionel Sambuc  * here. Used from within schedproc.h */
7433d6423SLionel Sambuc #define _MAIN
8433d6423SLionel Sambuc 
9433d6423SLionel Sambuc #include "sched.h"
10433d6423SLionel Sambuc #include "schedproc.h"
11433d6423SLionel Sambuc 
12433d6423SLionel Sambuc /* Declare some local functions. */
13433d6423SLionel Sambuc static void reply(endpoint_t whom, message *m_ptr);
14433d6423SLionel Sambuc static void sef_local_startup(void);
15*3f82ac6aSCristiano Giuffrida static int sef_cb_init_fresh(int type, sef_init_info_t *info);
16433d6423SLionel Sambuc 
17433d6423SLionel Sambuc struct machine machine;		/* machine info */
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc /*===========================================================================*
20433d6423SLionel Sambuc  *				main					     *
21433d6423SLionel Sambuc  *===========================================================================*/
main(void)22433d6423SLionel Sambuc int main(void)
23433d6423SLionel Sambuc {
24433d6423SLionel Sambuc 	/* Main routine of the scheduler. */
25433d6423SLionel Sambuc 	message m_in;	/* the incoming message itself is kept here. */
26433d6423SLionel Sambuc 	int call_nr;	/* system call number */
27433d6423SLionel Sambuc 	int who_e;	/* caller's endpoint */
28433d6423SLionel Sambuc 	int result;	/* result to system call */
29433d6423SLionel Sambuc 	int rv;
30433d6423SLionel Sambuc 
31433d6423SLionel Sambuc 	/* SEF local startup. */
32433d6423SLionel Sambuc 	sef_local_startup();
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc 	/* This is SCHED's main loop - get work and do it, forever and forever. */
35433d6423SLionel Sambuc 	while (TRUE) {
36433d6423SLionel Sambuc 		int ipc_status;
37433d6423SLionel Sambuc 
38433d6423SLionel Sambuc 		/* Wait for the next message and extract useful information from it. */
39433d6423SLionel Sambuc 		if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
40433d6423SLionel Sambuc 			panic("SCHED sef_receive error");
41433d6423SLionel Sambuc 		who_e = m_in.m_source;	/* who sent the message */
42433d6423SLionel Sambuc 		call_nr = m_in.m_type;	/* system call number */
43433d6423SLionel Sambuc 
44433d6423SLionel Sambuc 		/* Check for system notifications first. Special cases. */
45433d6423SLionel Sambuc 		if (is_ipc_notify(ipc_status)) {
46433d6423SLionel Sambuc 			switch(who_e) {
47433d6423SLionel Sambuc 			case CLOCK:
486c31058dSDavid van Moolenbroek 				balance_queues();
496c31058dSDavid van Moolenbroek 				break;
50433d6423SLionel Sambuc 			default :
516c31058dSDavid van Moolenbroek 				break;
52433d6423SLionel Sambuc 			}
53433d6423SLionel Sambuc 
546c31058dSDavid van Moolenbroek 			continue; /* Don't reply. */
55433d6423SLionel Sambuc 		}
56433d6423SLionel Sambuc 
57433d6423SLionel Sambuc 		switch(call_nr) {
58433d6423SLionel Sambuc 		case SCHEDULING_INHERIT:
59433d6423SLionel Sambuc 		case SCHEDULING_START:
60433d6423SLionel Sambuc 			result = do_start_scheduling(&m_in);
61433d6423SLionel Sambuc 			break;
62433d6423SLionel Sambuc 		case SCHEDULING_STOP:
63433d6423SLionel Sambuc 			result = do_stop_scheduling(&m_in);
64433d6423SLionel Sambuc 			break;
65433d6423SLionel Sambuc 		case SCHEDULING_SET_NICE:
66433d6423SLionel Sambuc 			result = do_nice(&m_in);
67433d6423SLionel Sambuc 			break;
68433d6423SLionel Sambuc 		case SCHEDULING_NO_QUANTUM:
69433d6423SLionel Sambuc 			/* This message was sent from the kernel, don't reply */
70433d6423SLionel Sambuc 			if (IPC_STATUS_FLAGS_TEST(ipc_status,
71433d6423SLionel Sambuc 				IPC_FLG_MSG_FROM_KERNEL)) {
72433d6423SLionel Sambuc 				if ((rv = do_noquantum(&m_in)) != (OK)) {
73433d6423SLionel Sambuc 					printf("SCHED: Warning, do_noquantum "
74433d6423SLionel Sambuc 						"failed with %d\n", rv);
75433d6423SLionel Sambuc 				}
76433d6423SLionel Sambuc 				continue; /* Don't reply */
77433d6423SLionel Sambuc 			}
78433d6423SLionel Sambuc 			else {
79433d6423SLionel Sambuc 				printf("SCHED: process %d faked "
80433d6423SLionel Sambuc 					"SCHEDULING_NO_QUANTUM message!\n",
81433d6423SLionel Sambuc 						who_e);
82433d6423SLionel Sambuc 				result = EPERM;
83433d6423SLionel Sambuc 			}
84433d6423SLionel Sambuc 			break;
85433d6423SLionel Sambuc 		default:
86433d6423SLionel Sambuc 			result = no_sys(who_e, call_nr);
87433d6423SLionel Sambuc 		}
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc 		/* Send reply. */
90433d6423SLionel Sambuc 		if (result != SUSPEND) {
91433d6423SLionel Sambuc 			m_in.m_type = result;  		/* build reply message */
92433d6423SLionel Sambuc 			reply(who_e, &m_in);		/* send it away */
93433d6423SLionel Sambuc 		}
94433d6423SLionel Sambuc  	}
95433d6423SLionel Sambuc 	return(OK);
96433d6423SLionel Sambuc }
97433d6423SLionel Sambuc 
98433d6423SLionel Sambuc /*===========================================================================*
99433d6423SLionel Sambuc  *				reply					     *
100433d6423SLionel Sambuc  *===========================================================================*/
reply(endpoint_t who_e,message * m_ptr)101433d6423SLionel Sambuc static void reply(endpoint_t who_e, message *m_ptr)
102433d6423SLionel Sambuc {
103433d6423SLionel Sambuc 	int s = ipc_send(who_e, m_ptr);    /* send the message */
104433d6423SLionel Sambuc 	if (OK != s)
105433d6423SLionel Sambuc 		printf("SCHED: unable to send reply to %d: %d\n", who_e, s);
106433d6423SLionel Sambuc }
107433d6423SLionel Sambuc 
108433d6423SLionel Sambuc /*===========================================================================*
109433d6423SLionel Sambuc  *			       sef_local_startup			     *
110433d6423SLionel Sambuc  *===========================================================================*/
sef_local_startup(void)111433d6423SLionel Sambuc static void sef_local_startup(void)
112433d6423SLionel Sambuc {
113*3f82ac6aSCristiano Giuffrida 	/* Register init callbacks. */
114*3f82ac6aSCristiano Giuffrida 	sef_setcb_init_fresh(sef_cb_init_fresh);
115*3f82ac6aSCristiano Giuffrida 	sef_setcb_init_restart(SEF_CB_INIT_RESTART_STATEFUL);
116*3f82ac6aSCristiano Giuffrida 
117433d6423SLionel Sambuc 	/* No signal callbacks for now. */
118433d6423SLionel Sambuc 
119433d6423SLionel Sambuc 	/* Let SEF perform startup. */
120433d6423SLionel Sambuc 	sef_startup();
121433d6423SLionel Sambuc }
122*3f82ac6aSCristiano Giuffrida 
123*3f82ac6aSCristiano Giuffrida /*===========================================================================*
124*3f82ac6aSCristiano Giuffrida  *		            sef_cb_init_fresh                                *
125*3f82ac6aSCristiano Giuffrida  *===========================================================================*/
sef_cb_init_fresh(int UNUSED (type),sef_init_info_t * UNUSED (info))126*3f82ac6aSCristiano Giuffrida static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
127*3f82ac6aSCristiano Giuffrida {
128*3f82ac6aSCristiano Giuffrida 	int s;
129*3f82ac6aSCristiano Giuffrida 
130*3f82ac6aSCristiano Giuffrida 	if (OK != (s=sys_getmachine(&machine)))
131*3f82ac6aSCristiano Giuffrida 		panic("couldn't get machine info: %d", s);
132*3f82ac6aSCristiano Giuffrida 	/* Initialize scheduling timers, used for running balance_queues */
133*3f82ac6aSCristiano Giuffrida 	init_scheduling();
134*3f82ac6aSCristiano Giuffrida 
135*3f82ac6aSCristiano Giuffrida 	return(OK);
136*3f82ac6aSCristiano Giuffrida }
137*3f82ac6aSCristiano Giuffrida 
138