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