113 lines
3.4 KiB
C
113 lines
3.4 KiB
C
#include "pm.h"
|
|
#include <assert.h>
|
|
#include <minix/callnr.h>
|
|
#include <minix/com.h>
|
|
#include <minix/config.h>
|
|
#include <minix/sched.h>
|
|
#include <minix/sysinfo.h>
|
|
#include <minix/type.h>
|
|
#include <machine/archtypes.h>
|
|
#include <lib.h>
|
|
#include "mproc.h"
|
|
|
|
#include <machine/archtypes.h>
|
|
#include <minix/timers.h>
|
|
#include "kernel/proc.h"
|
|
|
|
/*===========================================================================*
|
|
* init_scheduling *
|
|
*===========================================================================*/
|
|
void sched_init(void)
|
|
{
|
|
struct mproc *trmp;
|
|
endpoint_t parent_e;
|
|
int proc_nr, s;
|
|
|
|
for (proc_nr=0, trmp=mproc; proc_nr < NR_PROCS; proc_nr++, trmp++) {
|
|
/* Don't take over system processes. When the system starts,
|
|
* init is blocked on RTS_NO_QUANTUM until PM assigns a
|
|
* scheduler, from which other. Given that all other user
|
|
* processes are forked from init and system processes are
|
|
* managed by RS, there should be no other process that needs
|
|
* to be assigned a scheduler here */
|
|
if (trmp->mp_flags & IN_USE && !(trmp->mp_flags & PRIV_PROC)) {
|
|
assert(_ENDPOINT_P(trmp->mp_endpoint) == INIT_PROC_NR);
|
|
parent_e = mproc[trmp->mp_parent].mp_endpoint;
|
|
assert(parent_e == trmp->mp_endpoint);
|
|
s = sched_start(SCHED_PROC_NR, /* scheduler_e */
|
|
trmp->mp_endpoint, /* schedulee_e */
|
|
parent_e, /* parent_e */
|
|
USER_Q, /* maxprio */
|
|
USER_QUANTUM, /* quantum */
|
|
-1, /* don't change cpu */
|
|
&trmp->mp_scheduler); /* *newsched_e */
|
|
if (s != OK) {
|
|
printf("PM: SCHED denied taking over scheduling of %s: %d\n",
|
|
trmp->mp_name, s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* sched_start_user *
|
|
*===========================================================================*/
|
|
int sched_start_user(endpoint_t ep, struct mproc *rmp)
|
|
{
|
|
unsigned maxprio;
|
|
endpoint_t inherit_from;
|
|
int rv;
|
|
|
|
/* convert nice to priority */
|
|
if ((rv = nice_to_priority(rmp->mp_nice, &maxprio)) != OK) {
|
|
return rv;
|
|
}
|
|
|
|
/* scheduler must know the parent, which is not the case for a child
|
|
* of a system process created by a regular fork; in this case the
|
|
* scheduler should inherit settings from init rather than the real
|
|
* parent
|
|
*/
|
|
if (mproc[rmp->mp_parent].mp_flags & PRIV_PROC) {
|
|
assert(mproc[rmp->mp_parent].mp_scheduler == NONE);
|
|
inherit_from = INIT_PROC_NR;
|
|
} else {
|
|
inherit_from = mproc[rmp->mp_parent].mp_endpoint;
|
|
}
|
|
|
|
/* inherit quantum */
|
|
return sched_inherit(ep, /* scheduler_e */
|
|
rmp->mp_endpoint, /* schedulee_e */
|
|
inherit_from, /* parent_e */
|
|
maxprio, /* maxprio */
|
|
&rmp->mp_scheduler); /* *newsched_e */
|
|
}
|
|
|
|
/*===========================================================================*
|
|
* sched_nice *
|
|
*===========================================================================*/
|
|
int sched_nice(struct mproc *rmp, int nice)
|
|
{
|
|
int rv;
|
|
message m;
|
|
unsigned maxprio;
|
|
|
|
/* If the kernel is the scheduler, we don't allow messing with the
|
|
* priority. If you want to control process priority, assign the process
|
|
* to a user-space scheduler */
|
|
if (rmp->mp_scheduler == KERNEL || rmp->mp_scheduler == NONE)
|
|
return (EINVAL);
|
|
|
|
if ((rv = nice_to_priority(nice, &maxprio)) != OK) {
|
|
return rv;
|
|
}
|
|
|
|
m.m_pm_sched_scheduling_set_nice.endpoint = rmp->mp_endpoint;
|
|
m.m_pm_sched_scheduling_set_nice.maxprio = maxprio;
|
|
if ((rv = _taskcall(rmp->mp_scheduler, SCHEDULING_SET_NICE, &m))) {
|
|
return rv;
|
|
}
|
|
|
|
return (OK);
|
|
}
|