]> Zhao Yanbai Git Server - minix.git/commitdiff
SMP - Balancing run queues for SMP
authorTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:51 +0000 (14:10 +0000)
committerTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:51 +0000 (14:10 +0000)
- it preempts running processes though :( this is not the final
  solution

kernel/system.c
servers/sched/schedule.c

index 6e02000dac243ad7f28080061fb702d7a1300d78..14454009e123f1e5559ce1c1da0bf135cdd68ee4 100644 (file)
@@ -662,11 +662,14 @@ PUBLIC int sched_proc(struct proc *p,
 
        /* FIXME this is a problem for SMP if the processes currently runs on a
         * different CPU */
-       if (proc_is_runnable(p) && p->p_cpu != cpuid &&
-                       (cpu != -1 || cpu != p->p_cpu)) {
-               printf("WARNING : changing cpu of a runnable process %d "
-                               "on a different cpu!\n", p->p_endpoint);
-               return(EINVAL);
+       if (proc_is_runnable(p)) {
+               if (p->p_cpu != cpuid && cpu != -1 && cpu != p->p_cpu) {
+                       printf("WARNING : changing cpu of a runnable process %d "
+                                       "on a different cpu!\n", p->p_endpoint);
+                       return(EINVAL);
+               }
+
+               RTS_SET(p, RTS_NO_QUANTUM);
        }
 
        if (proc_is_runnable(p))
index 97e9674f940af464ce9c635fb4c940ed47968561..4e1e24ca31fd4874aed4552c0094c7ea645b9799 100644 (file)
@@ -19,9 +19,25 @@ PRIVATE unsigned balance_timeout;
 
 #define BALANCE_TIMEOUT        5 /* how often to balance queues in seconds */
 
-FORWARD _PROTOTYPE( int schedule_process, (struct schedproc * rmp)     );
+FORWARD _PROTOTYPE( int schedule_process, (struct schedproc * rmp,
+                       unsigned flags));
 FORWARD _PROTOTYPE( void balance_queues, (struct timer *tp)            );
 
+#define SCHEDULE_CHANGE_PRIO   0x1
+#define SCHEDULE_CHANGE_QUANTUM        0x2
+#define SCHEDULE_CHANGE_CPU    0x4
+
+#define SCHEDULE_CHANGE_ALL    (       \
+               SCHEDULE_CHANGE_PRIO    |       \
+               SCHEDULE_CHANGE_QUANTUM |       \
+               SCHEDULE_CHANGE_CPU             \
+               )
+
+#define schedule_process_local(p)      \
+       schedule_process(p, SCHEDULE_CHANGE_PRIO | SCHEDULE_CHANGE_QUANTUM)
+#define schedule_process_migrate(p)    \
+       schedule_process(p, SCHEDULE_CHANGE_CPU)
+
 #define DEFAULT_USER_TIME_SLICE 200
 
 /* processes created by RS are sysytem processes */
@@ -79,7 +95,7 @@ PUBLIC int do_noquantum(message *m_ptr)
                rmp->priority += 1; /* lower priority */
        }
 
-       if ((rv = schedule_process(rmp)) != OK) {
+       if ((rv = schedule_process_local(rmp)) != OK) {
                return rv;
        }
        return OK;
@@ -197,7 +213,8 @@ PUBLIC int do_start_scheduling(message *m_ptr)
        rmp->flags = IN_USE;
 
        /* Schedule the process, giving it some quantum */
-       if ((rv = schedule_process(rmp)) != OK) {
+       pick_cpu(rmp);
+       if ((rv = schedule_process(rmp, SCHEDULE_CHANGE_ALL)) != OK) {
                printf("Sched: Error while scheduling process, kernel replied %d\n",
                        rv);
                return rv;
@@ -248,7 +265,7 @@ PUBLIC int do_nice(message *m_ptr)
        /* Update the proc entry and reschedule the process */
        rmp->max_priority = rmp->priority = new_q;
 
-       if ((rv = schedule_process(rmp)) != OK) {
+       if ((rv = schedule_process_local(rmp)) != OK) {
                /* Something went wrong when rescheduling the process, roll
                 * back the changes to proc struct */
                rmp->priority     = old_q;
@@ -261,19 +278,35 @@ PUBLIC int do_nice(message *m_ptr)
 /*===========================================================================*
  *                             schedule_process                             *
  *===========================================================================*/
-PRIVATE int schedule_process(struct schedproc * rmp)
+PRIVATE int schedule_process(struct schedproc * rmp, unsigned flags)
 {
-       int rv;
+       int err;
+       int new_prio, new_quantum, new_cpu;
 
        pick_cpu(rmp);
 
-       if ((rv = sys_schedule(rmp->endpoint, rmp->priority,
-                       rmp->time_slice, rmp->cpu)) != OK) {
-               printf("SCHED: An error occurred when trying to schedule %d: %d\n",
-               rmp->endpoint, rv);
+       if (flags & SCHEDULE_CHANGE_PRIO)
+               new_prio = rmp->priority;
+       else
+               new_prio = -1;
+
+       if (flags & SCHEDULE_CHANGE_QUANTUM)
+               new_quantum = rmp->time_slice;
+       else
+               new_quantum = -1;
+
+       if (flags & SCHEDULE_CHANGE_CPU)
+               new_cpu = rmp->cpu;
+       else
+               new_cpu = -1;
+
+       if ((err = sys_schedule(rmp->endpoint, new_prio,
+               new_quantum, new_cpu)) != OK) {
+               printf("PM: An error occurred when trying to schedule %d: %d\n",
+               rmp->endpoint, err);
        }
 
-       return rv;
+       return err;
 }
 
 
@@ -307,7 +340,7 @@ PRIVATE void balance_queues(struct timer *tp)
                if (rmp->flags & IN_USE) {
                        if (rmp->priority > rmp->max_priority) {
                                rmp->priority -= 1; /* increase priority */
-                               schedule_process(rmp);
+                               schedule_process_local(rmp);
                        }
                }
        }