1 /*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)proc_compare.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 /* 13 * Returns 1 if p2 is more active than p1 14 * 15 * The algorithm for picking the "more active" process is thus: 16 * 17 * 1) Runnable processes are favored over anything 18 * else. The runner with the highest cpu 19 * utilization is picked (p_cpu). Ties are 20 * broken by picking the highest pid. 21 * 2) Next, the sleeper with the shortest sleep 22 * time is favored. With ties, we pick out 23 * just short-term sleepers (p_pri <= PZERO). 24 * Further ties are broken by picking the highest 25 * pid. 26 * 27 * NOTE - if you change this, be sure to consider making 28 * the change in the kernel too (^T in kern/tty.c). 29 * 30 * TODO - consider whether pctcpu should be used 31 * 32 */ 33 34 #include <sys/param.h> 35 #include <sys/time.h> 36 #include <sys/proc.h> 37 38 #include "extern.h" 39 40 #define isrun(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 41 42 #define TESTAB(a, b) ((a)<<1 | (b)) 43 #define ONLYA 2 44 #define ONLYB 1 45 #define BOTH 3 46 47 int 48 proc_compare(p1, p2) 49 register struct proc *p1, *p2; 50 { 51 52 if (p1 == NULL) 53 return (1); 54 /* 55 * see if at least one of them is runnable 56 */ 57 switch (TESTAB(isrun(p1), isrun(p2))) { 58 case ONLYA: 59 return (0); 60 case ONLYB: 61 return (1); 62 case BOTH: 63 /* 64 * tie - favor one with highest recent cpu utilization 65 */ 66 if (p2->p_cpu > p1->p_cpu) 67 return (1); 68 if (p1->p_cpu > p2->p_cpu) 69 return (0); 70 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 71 } 72 /* 73 * weed out zombies 74 */ 75 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 76 case ONLYA: 77 return (1); 78 case ONLYB: 79 return (0); 80 case BOTH: 81 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 82 } 83 /* 84 * pick the one with the smallest sleep time 85 */ 86 if (p2->p_slptime > p1->p_slptime) 87 return (0); 88 if (p1->p_slptime > p2->p_slptime) 89 return (1); 90 /* 91 * favor one sleeping in a non-interruptible sleep 92 */ 93 if (p1->p_flag&SSINTR && (p2->p_flag&SSINTR) == 0) 94 return (1); 95 if (p2->p_flag&SSINTR && (p1->p_flag&SSINTR) == 0) 96 return (0); 97 return(p2->p_pid > p1->p_pid); /* tie - return highest pid */ 98 } 99