From: Jorrit Herder Date: Tue, 23 Aug 2005 10:25:01 +0000 (+0000) Subject: Improved scheduling: new way to catch infinite loops. X-Git-Tag: v3.1.0~304 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.html?a=commitdiff_plain;h=5ecb45c3469a3e03d5f5e748385239f73cffb6b9;p=minix.git Improved scheduling: new way to catch infinite loops. --- diff --git a/kernel/proc.c b/kernel/proc.c index ad78e26f6..1dac41ff3 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -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 diff --git a/kernel/table.c b/kernel/table.c index 71dcc07b6..57cbeb767 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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" }, };