141389Smarc /*- 262433Sbostic * Copyright (c) 1990, 1993 362433Sbostic * The Regents of the University of California. All rights reserved. 441389Smarc * 541389Smarc * %sccs.include.redist.c% 641389Smarc */ 741389Smarc 841389Smarc #ifndef lint 9*64640Sbostic static char sccsid[] = "@(#)proc_compare.c 8.2 (Berkeley) 09/23/93"; 1041389Smarc #endif /* not lint */ 1141389Smarc 12*64640Sbostic #include <sys/param.h> 13*64640Sbostic #include <sys/time.h> 14*64640Sbostic #include <sys/proc.h> 15*64640Sbostic 16*64640Sbostic #include "extern.h" 17*64640Sbostic 1841389Smarc /* 19*64640Sbostic * Returns 1 if p2 is "better" than p1 2041389Smarc * 21*64640Sbostic * The algorithm for picking the "interesting" process is thus: 2241389Smarc * 23*64640Sbostic * 1) Only foreground processes are eligible - implied. 24*64640Sbostic * 2) Runnable processes are favored over anything else. The runner 25*64640Sbostic * with the highest cpu utilization is picked (p_estcpu). Ties are 2641389Smarc * broken by picking the highest pid. 27*64640Sbostic * 3) The sleeper with the shortest sleep time is next. With ties, 28*64640Sbostic * we pick out just "short-term" sleepers (P_SINTR == 0). 29*64640Sbostic * 4) Further ties are broken by picking the highest pid. 3041389Smarc * 31*64640Sbostic * If you change this, be sure to consider making the change in the kernel 32*64640Sbostic * too (^T in kern/tty.c). 3341389Smarc * 34*64640Sbostic * TODO - consider whether pctcpu should be used. 3541389Smarc */ 3641391Smarc 37*64640Sbostic #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) 38*64640Sbostic #define TESTAB(a, b) ((a)<<1 | (b)) 39*64640Sbostic #define ONLYA 2 40*64640Sbostic #define ONLYB 1 41*64640Sbostic #define BOTH 3 4241391Smarc 4359360Sbostic int proc_compare(p1,p2)4441389Smarcproc_compare(p1, p2) 4541389Smarc register struct proc *p1, *p2; 4641389Smarc { 4741389Smarc 4841389Smarc if (p1 == NULL) 4941389Smarc return (1); 5041389Smarc /* 5141389Smarc * see if at least one of them is runnable 5241389Smarc */ 53*64640Sbostic switch (TESTAB(ISRUN(p1), ISRUN(p2))) { 5444294Smarc case ONLYA: 5546317Smarc return (0); 5646317Smarc case ONLYB: 5741389Smarc return (1); 5844294Smarc case BOTH: 5941389Smarc /* 6041389Smarc * tie - favor one with highest recent cpu utilization 6141389Smarc */ 62*64640Sbostic if (p2->p_estcpu > p1->p_estcpu) 6341389Smarc return (1); 64*64640Sbostic if (p1->p_estcpu > p2->p_estcpu) 6541389Smarc return (0); 6641389Smarc return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 6741389Smarc } 6844294Smarc /* 69*64640Sbostic * weed out zombies 7044294Smarc */ 7144294Smarc switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { 7244294Smarc case ONLYA: 7344294Smarc return (1); 7444294Smarc case ONLYB: 7544294Smarc return (0); 7644294Smarc case BOTH: 77*64640Sbostic return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 7844294Smarc } 79*64640Sbostic /* 8041389Smarc * pick the one with the smallest sleep time 8141389Smarc */ 8241389Smarc if (p2->p_slptime > p1->p_slptime) 8341389Smarc return (0); 8441389Smarc if (p1->p_slptime > p2->p_slptime) 8541389Smarc return (1); 8641389Smarc /* 8741389Smarc * favor one sleeping in a non-interruptible sleep 8841389Smarc */ 89*64640Sbostic if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0) 90*64640Sbostic return (1); 91*64640Sbostic if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0) 92*64640Sbostic return (0); 93*64640Sbostic return (p2->p_pid > p1->p_pid); /* tie - return highest pid */ 9441389Smarc } 95