FORWARD _PROTOTYPE( void reply, (endpoint_t whom, message *m_ptr) );
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
+PUBLIC struct machine machine; /* machine info */
+
/*===========================================================================*
* main *
*===========================================================================*/
int who_e; /* caller's endpoint */
int result; /* result to system call */
int rv;
+ int s;
/* SEF local startup. */
sef_local_startup();
+ if (OK != (s=sys_getmachine(&machine)))
+ panic("couldn't get machine info: %d", s);
/* Initialize scheduling timers, used for running balance_queues */
init_scheduling();
*/
#include <limits.h>
+#include <minix/bitmap.h>
+
/* EXTERN should be extern except in main.c, where we want to keep the struct */
#ifdef _MAIN
#undef EXTERN
unsigned max_priority; /* this process' highest allowed priority */
unsigned priority; /* the process' current priority */
unsigned time_slice; /* this process's time slice */
+ unsigned cpu; /* what CPU is the process running on */
+ bitchunk_t cpu_mask[BITMAP_CHUNKS(CONFIG_MAX_CPUS)]; /* what CPUs is hte
+ process allowed
+ to run on */
} schedproc[NR_PROCS];
/* Flag values */
#define DEFAULT_USER_TIME_SLICE 200
+/* processes created by RS are sysytem processes */
+#define is_system_proc(p) ((p)->parent == RS_PROC_NR)
+
+PRIVATE unsigned cpu_proc[CONFIG_MAX_CPUS];
+
+PRIVATE void pick_cpu(struct schedproc * proc)
+{
+#ifdef CONFIG_SMP
+ unsigned cpu, c;
+ unsigned cpu_load = (unsigned) -1;
+
+ if (machine.processors_count == 1) {
+ proc->cpu = machine.bsp_id;
+ return;
+ }
+
+ /* schedule sysytem processes only on the boot cpu */
+ if (is_system_proc(proc)) {
+ proc->cpu = machine.bsp_id;
+ return;
+ }
+
+ for (c = 0; c < machine.processors_count; c++) {
+ if (c != machine.bsp_id && cpu_load > cpu_proc[c]) {
+ cpu_load = cpu_proc[c];
+ cpu = c;
+ }
+ }
+ proc->cpu = cpu;
+ cpu_proc[cpu]++;
+#else
+ proc->cpu = 0;
+#endif
+}
+
/*===========================================================================*
* do_noquantum *
*===========================================================================*/
}
rmp = &schedproc[proc_nr_n];
+ cpu_proc[rmp->cpu]--;
rmp->flags = 0; /*&= ~IN_USE;*/
return OK;
if (rmp->max_priority >= NR_SCHED_QUEUES) {
return EINVAL;
}
+
+ /* Inherit current priority and time slice from parent. Since there
+ * is currently only one scheduler scheduling the whole system, this
+ * value is local and we assert that the parent endpoint is valid */
+ if (rmp->endpoint == rmp->parent) {
+ /* We have a special case here for init, which is the first
+ process scheduled, and the parent of itself. */
+ rmp->priority = USER_Q;
+ rmp->time_slice = DEFAULT_USER_TIME_SLICE;
+
+ /*
+ * Since kernel never changes the cpu of a process, all are
+ * started on the BSP and the userspace scheduling hasn't
+ * changed that yet either, we can be sure that BSP is the
+ * processor where the processes run now.
+ */
+ rmp->cpu = machine.bsp_id;
+ /* FIXME set the cpu mask */
+ }
switch (m_ptr->m_type) {
{
int rv;
+ pick_cpu(rmp);
+
if ((rv = sys_schedule(rmp->endpoint, rmp->priority,
rmp->time_slice)) != OK) {
printf("SCHED: An error occurred when trying to schedule %d: %d\n",