xref: /csrg-svn/usr.bin/w/proc_compare.c (revision 64640)
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)4441389Smarc proc_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