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