Commit | Line | Data |
---|---|---|
00fe0339 MT |
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 | |
f96f3040 | 9 | static char sccsid[] = "@(#)proc_compare.c 5.4 (Berkeley) %G%"; |
00fe0339 MT |
10 | #endif /* not lint */ |
11 | ||
12 | /* | |
13 | * Returns 1 if p2 is more active than p1 | |
14 | * | |
d715ab21 | 15 | * The algorithm for picking the "more active" process is thus: |
00fe0339 MT |
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 | * | |
d715ab21 MT |
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 | |
00fe0339 MT |
31 | * |
32 | */ | |
d715ab21 MT |
33 | |
34 | #include <sys/param.h> | |
35 | #include <sys/time.h> | |
36 | #include <sys/proc.h> | |
37 | ||
00fe0339 | 38 | #define isrun(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL)) |
d715ab21 | 39 | |
41a3e0d2 | 40 | #define TESTAB(a, b) ((a)<<1 | (b)) |
f96f3040 MT |
41 | #define ONLYA 2 |
42 | #define ONLYB 1 | |
43 | #define BOTH 3 | |
41a3e0d2 | 44 | |
00fe0339 MT |
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 | */ | |
41a3e0d2 MT |
54 | switch (TESTAB(isrun(p1), isrun(p2))) { |
55 | case ONLYA: | |
00fe0339 | 56 | return (0); |
f96f3040 MT |
57 | case ONLYB: |
58 | return (1); | |
41a3e0d2 | 59 | case BOTH: |
00fe0339 MT |
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 | } | |
41a3e0d2 MT |
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 | } | |
00fe0339 MT |
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 | } |