xref: /original-bsd/usr.bin/w/proc_compare.c (revision feb5f8e2)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)proc_compare.c	5.4 (Berkeley) 02/07/91";
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 #define isrun(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
39 
40 #define	TESTAB(a, b)	((a)<<1 | (b))
41 #define	ONLYA	2
42 #define	ONLYB	1
43 #define	BOTH	3
44 
45 proc_compare(p1, p2)
46 	register struct proc *p1, *p2;
47 {
48 
49 	if (p1 == NULL)
50 		return (1);
51 	/*
52 	 * see if at least one of them is runnable
53 	 */
54 	switch (TESTAB(isrun(p1), isrun(p2))) {
55 	case ONLYA:
56 		return (0);
57 	case ONLYB:
58 		return (1);
59 	case BOTH:
60 		/*
61 		 * tie - favor one with highest recent cpu utilization
62 		 */
63 		if (p2->p_cpu > p1->p_cpu)
64 			return (1);
65 		if (p1->p_cpu > p2->p_cpu)
66 			return (0);
67 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
68 	}
69 	/*
70 	 * weed out zombies
71 	 */
72 	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
73 	case ONLYA:
74 		return (1);
75 	case ONLYB:
76 		return (0);
77 	case BOTH:
78 		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
79 	}
80 	/*
81 	 * pick the one with the smallest sleep time
82 	 */
83 	if (p2->p_slptime > p1->p_slptime)
84 		return (0);
85 	if (p1->p_slptime > p2->p_slptime)
86 		return (1);
87 	/*
88 	 * favor one sleeping in a non-interruptible sleep
89 	 */
90 	 if (p1->p_flag&SSINTR && (p2->p_flag&SSINTR) == 0)
91 		 return (1);
92 	 if (p2->p_flag&SSINTR && (p1->p_flag&SSINTR) == 0)
93 		 return (0);
94 	return(p2->p_pid > p1->p_pid);		/* tie - return highest pid */
95 }
96