xref: /minix3/minix/servers/pm/schedule.c (revision 36dcc4a4a93f782ada76dce3d52fbeab0e063cf1)
1 #include "pm.h"
2 #include <assert.h>
3 #include <minix/callnr.h>
4 #include <minix/com.h>
5 #include <minix/config.h>
6 #include <minix/sched.h>
7 #include <minix/sysinfo.h>
8 #include <minix/type.h>
9 #include <machine/archtypes.h>
10 #include <lib.h>
11 #include "mproc.h"
12 
13 #include <machine/archtypes.h>
14 #include <minix/timers.h>
15 #include "kernel/proc.h"
16 
17 /*===========================================================================*
18  *				init_scheduling				     *
19  *===========================================================================*/
20 void sched_init(void)
21 {
22 	struct mproc *trmp;
23 	endpoint_t parent_e;
24 	int proc_nr, s;
25 
26 	for (proc_nr=0, trmp=mproc; proc_nr < NR_PROCS; proc_nr++, trmp++) {
27 		/* Don't take over system processes. When the system starts,
28 		 * init is blocked on RTS_NO_QUANTUM until PM assigns a
29 		 * scheduler, from which other. Given that all other user
30 		 * processes are forked from init and system processes are
31 		 * managed by RS, there should be no other process that needs
32 		 * to be assigned a scheduler here */
33 		if (trmp->mp_flags & IN_USE && !(trmp->mp_flags & PRIV_PROC)) {
34 			assert(_ENDPOINT_P(trmp->mp_endpoint) == INIT_PROC_NR);
35 			parent_e = mproc[trmp->mp_parent].mp_endpoint;
36 			assert(parent_e == trmp->mp_endpoint);
37 			s = sched_start(SCHED_PROC_NR,	/* scheduler_e */
38 				trmp->mp_endpoint,	/* schedulee_e */
39 				parent_e,		/* parent_e */
40 				USER_Q, 		/* maxprio */
41 				USER_QUANTUM, 		/* quantum */
42 				-1,			/* don't change cpu */
43 				&trmp->mp_scheduler);	/* *newsched_e */
44 			if (s != OK) {
45 				printf("PM: SCHED denied taking over scheduling of %s: %d\n",
46 					trmp->mp_name, s);
47 			}
48 		}
49  	}
50 }
51 
52 /*===========================================================================*
53  *				sched_start_user			     *
54  *===========================================================================*/
55 int sched_start_user(endpoint_t ep, struct mproc *rmp)
56 {
57 	unsigned maxprio;
58 	endpoint_t inherit_from;
59 	int rv;
60 
61 	/* convert nice to priority */
62 	if ((rv = nice_to_priority(rmp->mp_nice, &maxprio)) != OK) {
63 		return rv;
64 	}
65 
66 	/* scheduler must know the parent, which is not the case for a child
67 	 * of a system process created by a regular fork; in this case the
68 	 * scheduler should inherit settings from init rather than the real
69 	 * parent
70 	 */
71 	if (mproc[rmp->mp_parent].mp_flags & PRIV_PROC) {
72 		assert(mproc[rmp->mp_parent].mp_scheduler == NONE);
73 		inherit_from = INIT_PROC_NR;
74 	} else {
75 		inherit_from = mproc[rmp->mp_parent].mp_endpoint;
76 	}
77 
78 	/* inherit quantum */
79 	return sched_inherit(ep, 			/* scheduler_e */
80 		rmp->mp_endpoint, 			/* schedulee_e */
81 		inherit_from, 				/* parent_e */
82 		maxprio, 				/* maxprio */
83 		&rmp->mp_scheduler);			/* *newsched_e */
84 }
85 
86 /*===========================================================================*
87  *				sched_nice				     *
88  *===========================================================================*/
89 int sched_nice(struct mproc *rmp, int nice)
90 {
91 	int rv;
92 	message m;
93 	unsigned maxprio;
94 
95 	/* If the kernel is the scheduler, we don't allow messing with the
96 	 * priority. If you want to control process priority, assign the process
97 	 * to a user-space scheduler */
98 	if (rmp->mp_scheduler == KERNEL || rmp->mp_scheduler == NONE)
99 		return (EINVAL);
100 
101 	if ((rv = nice_to_priority(nice, &maxprio)) != OK) {
102 		return rv;
103 	}
104 
105 	m.m_pm_sched_scheduling_set_nice.endpoint	= rmp->mp_endpoint;
106 	m.m_pm_sched_scheduling_set_nice.maxprio	= maxprio;
107 	if ((rv = _taskcall(rmp->mp_scheduler, SCHEDULING_SET_NICE, &m))) {
108 		return rv;
109 	}
110 
111 	return (OK);
112 }
113