xref: /original-bsd/usr.bin/w/proc_compare.c (revision c3e32dec)
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