GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/w/proc_compare.c Lines: 0 23 0.0 %
Date: 2017-11-07 Branches: 0 34 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: proc_compare.c,v 1.15 2015/01/16 06:40:14 deraadt Exp $	*/
2
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. Neither the name of the University nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 */
31
32
#include <sys/param.h>	/* MAXCOMLEN */
33
#include <sys/proc.h>
34
#include <sys/sysctl.h>
35
#include <sys/time.h>
36
37
#include "extern.h"
38
39
/*
40
 * Returns 1 if p2 is "better" than p1
41
 *
42
 * The algorithm for picking the "interesting" process is thus:
43
 *
44
 *	1) Only foreground processes are eligible - implied.
45
 *	2) Runnable processes are favored over anything else.  The runner
46
 *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
47
 *	   broken by picking the highest pid.
48
 *	3) The sleeper with the shortest sleep time is next.  With ties,
49
 *	   we pick out just "short-term" sleepers (P_SINTR == 0).
50
 *	4) Further ties are broken by picking the highest pid.
51
 *
52
 * If you change this, be sure to consider making the change in the kernel
53
 * too (^T in kern/tty.c).
54
 *
55
 * TODO - consider whether pctcpu should be used.
56
 */
57
58
#define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL) || \
59
			 ((p)->p_stat == SONPROC))
60
#define TESTAB(a, b)    ((a)<<1 | (b))
61
#define ONLYA   2
62
#define ONLYB   1
63
#define BOTH    3
64
65
int
66
proc_compare(const struct kinfo_proc *p1, const struct kinfo_proc *p2)
67
{
68
	if (p1 == NULL)
69
		return (1);
70
	/*
71
	 * see if at least one of them is runnable
72
	 */
73
	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
74
	case ONLYA:
75
		return (0);
76
	case ONLYB:
77
		return (1);
78
	case BOTH:
79
		/*
80
		 * tie - favor one with highest recent cpu utilization
81
		 */
82
		if (p2->p_estcpu > p1->p_estcpu)
83
			return (1);
84
		if (p1->p_estcpu > p2->p_estcpu)
85
			return (0);
86
		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
87
	}
88
	/*
89
	 * weed out zombies
90
	 */
91
	switch (TESTAB(p1->p_stat == SDEAD, p2->p_stat == SDEAD)) {
92
	case ONLYA:
93
		return (1);
94
	case ONLYB:
95
		return (0);
96
	case BOTH:
97
		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
98
	}
99
	/*
100
	 * pick the one with the smallest sleep time
101
	 */
102
	if (p2->p_slptime > p1->p_slptime)
103
		return (0);
104
	if (p1->p_slptime > p2->p_slptime)
105
		return (1);
106
	/*
107
	 * favor one sleeping in a non-interruptible sleep
108
	 */
109
	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
110
		return (1);
111
	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
112
		return (0);
113
	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
114
}