minix/servers/pm/schedule.c
2010-07-01 08:32:33 +00:00

98 lines
3 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 <timers.h>
#include "kernel/proc.h"
/*===========================================================================*
* init_scheduling *
*===========================================================================*/
PUBLIC 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 */
&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 *
*===========================================================================*/
PUBLIC int sched_start_user(endpoint_t ep, struct mproc *rmp)
{
unsigned maxprio;
int rv;
/* convert nice to priority */
if ((rv = nice_to_priority(rmp->mp_nice, &maxprio)) != OK) {
return rv;
}
/* inherit quantum */
return sched_inherit(ep, /* scheduler_e */
rmp->mp_endpoint, /* schedulee_e */
mproc[rmp->mp_parent].mp_endpoint, /* parent_e */
maxprio, /* maxprio */
&rmp->mp_scheduler); /* *newsched_e */
}
/*===========================================================================*
* sched_nice *
*===========================================================================*/
PUBLIC 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.SCHEDULING_ENDPOINT = rmp->mp_endpoint;
m.SCHEDULING_MAXPRIO = (int) maxprio;
if ((rv = _taskcall(rmp->mp_scheduler, SCHEDULING_SET_NICE, &m))) {
return rv;
}
return (OK);
}