Annotation of src/usr.bin/w/proc_compare.c, Revision 1.4
1.4 ! angelos 1: /* $OpenBSD: proc_compare.c,v 1.3 1998/01/16 17:50:43 millert Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1990, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #ifndef lint
1.3 millert 37: #if 0
1.1 deraadt 38: static char sccsid[] = "@(#)proc_compare.c 8.2 (Berkeley) 9/23/93";
1.3 millert 39: #else
1.4 ! angelos 40: static char *rcsid = "$OpenBSD: proc_compare.c,v 1.3 1998/01/16 17:50:43 millert Exp $";
1.3 millert 41: #endif
1.1 deraadt 42: #endif /* not lint */
43:
44: #include <sys/param.h>
45: #include <sys/time.h>
46: #include <sys/proc.h>
47:
48: #include "extern.h"
49:
50: /*
51: * Returns 1 if p2 is "better" than p1
52: *
53: * The algorithm for picking the "interesting" process is thus:
54: *
55: * 1) Only foreground processes are eligible - implied.
56: * 2) Runnable processes are favored over anything else. The runner
57: * with the highest cpu utilization is picked (p_estcpu). Ties are
58: * broken by picking the highest pid.
59: * 3) The sleeper with the shortest sleep time is next. With ties,
60: * we pick out just "short-term" sleepers (P_SINTR == 0).
61: * 4) Further ties are broken by picking the highest pid.
62: *
63: * If you change this, be sure to consider making the change in the kernel
64: * too (^T in kern/tty.c).
65: *
66: * TODO - consider whether pctcpu should be used.
67: */
68:
69: #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
70: #define TESTAB(a, b) ((a)<<1 | (b))
71: #define ONLYA 2
72: #define ONLYB 1
73: #define BOTH 3
74:
75: int
76: proc_compare(p1, p2)
77: register struct proc *p1, *p2;
78: {
79: if (p1 == NULL)
80: return (1);
81: /*
82: * see if at least one of them is runnable
83: */
84: switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
85: case ONLYA:
86: return (0);
87: case ONLYB:
88: return (1);
89: case BOTH:
90: /*
91: * tie - favor one with highest recent cpu utilization
92: */
93: if (p2->p_estcpu > p1->p_estcpu)
94: return (1);
95: if (p1->p_estcpu > p2->p_estcpu)
96: return (0);
97: return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
98: }
99: /*
100: * weed out zombies
101: */
102: switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
103: case ONLYA:
104: return (1);
105: case ONLYB:
106: return (0);
107: case BOTH:
108: return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
109: }
110: /*
111: * pick the one with the smallest sleep time
112: */
113: if (p2->p_slptime > p1->p_slptime)
114: return (0);
115: if (p1->p_slptime > p2->p_slptime)
116: return (1);
117: /*
118: * favor one sleeping in a non-interruptible sleep
119: */
120: if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
121: return (1);
122: if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
123: return (0);
124: return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
125: }