]> Zhao Yanbai Git Server - minix.git/commitdiff
Improved scheduling: new way to catch infinite loops.
authorJorrit Herder <jnherder@minix3.org>
Tue, 23 Aug 2005 10:25:01 +0000 (10:25 +0000)
committerJorrit Herder <jnherder@minix3.org>
Tue, 23 Aug 2005 10:25:01 +0000 (10:25 +0000)
kernel/proc.c
kernel/table.c

index ad78e26f690378f0761db772219e06e9db1b8a65..1dac41ff3177136eb64c5bd3a6a0347ff94d4424 100755 (executable)
@@ -491,30 +491,44 @@ register struct proc *rp;                 /* process to be scheduled */
 int *queue;                                    /* return: queue to use */
 int *front;                                    /* return: front or back */
 {
-/* This function determines the scheduling policy. It is called whenever a
+/* This function determines the scheduling policy.  It is called whenever a
  * process must be added to one of the scheduling queues to decide where to
- * insert it. 
+ * insert it.  As a side-effect the process' priority may be updated.  
  */
-  int time_left;
-  int penalty;
-
-  /* Check whether the process has time left. Otherwise give a new quantum.
+  static struct proc *prev_ptr = NIL_PROC;     /* previous without time */
+  int time_left = (rp->p_ticks_left > 0);      /* quantum fully consumed */
+  int penalty = 0;                             /* change in priority */
+
+  /* Check whether the process has time left. Otherwise give a new quantum 
+   * and possibly raise the priority.  Processes using multiple quantums 
+   * in a row get a lower priority to catch infinite loops in high priority
+   * processes (system servers and drivers). 
    */
-  time_left = (rp->p_ticks_left > 0);          /* check ticks left */
   if ( ! time_left) {                          /* quantum consumed ? */
       rp->p_ticks_left = rp->p_quantum_size;   /* give new quantum */
+      if (prev_ptr == rp) penalty ++;          /* catch infinite loops */
+      else penalty --;                                 /* give slow way back */
+      prev_ptr = rp;                           /* store ptr for next */
   }
 
-  /* Determine the new priority of this process. User and system processes
-   * are treated different. They can be distinguished because only user
-   * processes (and IDLE) are billable.
-   */
-  penalty = 0;
+#if 0
   if (priv(rp)->s_flags & BILLABLE) {          /* user process */
   }
   else {                                       /* system process */
   }
-  rp->p_priority = MIN((rp->p_max_priority + penalty), (IDLE_Q - 1));
+#endif
+
+  /* Determine the new priority of this process. The bounds are determined
+   * by IDLE's queue and the maximum priority of this process. Kernel task 
+   * and the idle process are never changed in priority.
+   */
+  if (! iskernelp(rp) && penalty != 0) {
+      rp->p_priority += penalty;               /* update with penalty */
+      if (rp->p_priority < rp->p_max_priority)  /* check upper bound */ 
+          rp->p_priority=rp->p_max_priority;
+      else if (rp->p_priority > IDLE_Q-1)      /* check lower bound */
+         rp->p_priority = IDLE_Q-1;
+  }
 
   /* If there is time left, the process is added to the front of its queue, 
    * so that it can immediately run. The queue to use simply is always the
index 71dcc07b6fa511dce99483456f3fbd760c83a9e9..57cbeb767a4828f4724e36d27064d38c7c23af20 100755 (executable)
@@ -101,11 +101,11 @@ PUBLIC struct boot_image image[] = {
  { HARDWARE,      0, TSK_F, 64, TASK_Q, HRD_S,     0,     0,     0, "KERNEL"},
  { PM_PROC_NR,    0, SRV_F, 32,      3, 0,     SRV_T, SRV_M,  PM_C, "pm"    },
  { FS_PROC_NR,    0, SRV_F, 32,      4, 0,     SRV_T, SRV_M,  FS_C, "fs"    },
- { SM_PROC_NR,    0, SRV_F, 32,      3, 0,     SRV_T, SYS_M,  SM_C, "sm"    },
- { TTY_PROC_NR,   0, SRV_F, 16,      1, 0,     SRV_T, SYS_M, DRV_C, "tty"   },
- { MEM_PROC_NR,   0, SRV_F, 16,      2, 0,     SRV_T, DRV_M, MEM_C, "memory"},
- { LOG_PROC_NR,   0, SRV_F, 16,      2, 0,     SRV_T, SYS_M, DRV_C, "log"   },
- { DRVR_PROC_NR,  0, SRV_F, 16,      2, 0,     SRV_T, SYS_M, DRV_C, "driver"},
+ { SM_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  SM_C, "sm"    },
+ { TTY_PROC_NR,   0, SRV_F,  4,      1, 0,     SRV_T, SYS_M, DRV_C, "tty"   },
+ { MEM_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, DRV_M, MEM_C, "memory"},
+ { LOG_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "log"   },
+ { DRVR_PROC_NR,  0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "driver"},
  { INIT_PROC_NR,  0, USR_F,  8, USER_Q, 0,     USR_T, USR_M,     0, "init"  },
 };