Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
c4ec2128 KM |
2 | * Copyright (c) 1982, 1986, 1989 Regents of the University of California. |
3 | * All rights reserved. | |
da7c5cc6 | 4 | * |
dbf0c423 | 5 | * %sccs.include.redist.c% |
c4ec2128 | 6 | * |
2e9bff25 | 7 | * @(#)vm_meter.c 7.12 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
e3bf9f41 | 9 | |
94368568 | 10 | #include "param.h" |
94368568 | 11 | #include "proc.h" |
ffe0d082 | 12 | #include "systm.h" |
94368568 | 13 | #include "kernel.h" |
2e9bff25 | 14 | #include "vm.h" |
e3bf9f41 | 15 | |
80b6b780 | 16 | fixpt_t averunnable[3]; /* load average, of runnable procs */ |
e3bf9f41 | 17 | |
f1f42678 KM |
18 | int maxslp = MAXSLP; |
19 | int saferss = SAFERSS; | |
e3bf9f41 | 20 | |
e3bf9f41 BJ |
21 | |
22 | vmmeter() | |
23 | { | |
24 | register unsigned *cp, *rp, *sp; | |
25 | ||
f1f42678 | 26 | if (time.tv_sec % 5 == 0) |
2e9bff25 | 27 | loadav(averunnable); |
ffe0d082 MK |
28 | if (proc0.p_slptime > maxslp/2) |
29 | wakeup((caddr_t)&proc0); | |
e3bf9f41 BJ |
30 | } |
31 | ||
e3bf9f41 BJ |
32 | /* |
33 | * Constants for averages over 1, 5, and 15 minutes | |
34 | * when sampling at 5 second intervals. | |
35 | */ | |
80b6b780 KM |
36 | fixpt_t cexp[3] = { |
37 | 0.9200444146293232 * FSCALE, /* exp(-1/12) */ | |
38 | 0.9834714538216174 * FSCALE, /* exp(-1/60) */ | |
39 | 0.9944598480048967 * FSCALE, /* exp(-1/180) */ | |
e3bf9f41 BJ |
40 | }; |
41 | ||
42 | /* | |
43 | * Compute a tenex style load average of a quantity on | |
44 | * 1, 5 and 15 minute intervals. | |
45 | */ | |
2e9bff25 | 46 | loadav(avg) |
80b6b780 | 47 | register fixpt_t *avg; |
e3bf9f41 | 48 | { |
2e9bff25 KM |
49 | register int i, nrun; |
50 | register struct proc *p; | |
e3bf9f41 | 51 | |
2e9bff25 KM |
52 | for (nrun = 0, p = allproc; p != NULL; p = p->p_nxt) { |
53 | switch (p->p_stat) { | |
54 | case SSLEEP: | |
55 | if (p->p_pri > PZERO || p->p_slptime != 0) | |
56 | continue; | |
57 | /* fall through */ | |
58 | case SRUN: | |
59 | case SIDL: | |
60 | nrun++; | |
61 | } | |
62 | } | |
e3bf9f41 | 63 | for (i = 0; i < 3; i++) |
2e9bff25 | 64 | avg[i] = (cexp[i] * avg[i] + nrun * FSCALE * (FSCALE - cexp[i])) |
80b6b780 | 65 | >> FSHIFT; |
b3b807e5 | 66 | #if defined(COMPAT_43) && (defined(vax) || defined(tahoe)) |
80b6b780 KM |
67 | for (i = 0; i < 3; i++) |
68 | avenrun[i] = (double) averunnable[i] / FSCALE; | |
69 | #endif /* COMPAT_43 */ | |
e3bf9f41 | 70 | } |
2e9bff25 KM |
71 | |
72 | /* | |
73 | * Calculate and return vmtotals structure. | |
74 | */ | |
75 | kinfo_meter(op, where, acopysize, arg, aneeded) | |
76 | int op; | |
77 | caddr_t where; | |
78 | int *acopysize, arg, *aneeded; | |
79 | { | |
80 | struct vmtotal vmtotals; | |
81 | int error; | |
82 | ||
83 | *aneeded = sizeof(struct vmtotal); | |
84 | if (where == NULL) | |
85 | return (0); | |
86 | if (*acopysize < sizeof(struct vmtotal)) | |
87 | return (EINVAL); | |
88 | vmtotal(&vmtotals); | |
89 | if (error = copyout((caddr_t)&vmtotals, where, sizeof(struct vmtotal))) | |
90 | return (error); | |
91 | *acopysize = sizeof(struct vmtotal); | |
92 | return (0); | |
93 | } | |
94 | ||
95 | /* | |
96 | * Calculate the current state of the system. | |
97 | * Done on demand from getkerninfo(). | |
98 | */ | |
99 | vmtotal(totalp) | |
100 | register struct vmtotal *totalp; | |
101 | { | |
102 | register struct proc *p; | |
103 | register vm_map_entry_t entry; | |
104 | register vm_object_t object; | |
105 | register vm_map_t map; | |
106 | int paging; | |
107 | ||
108 | bzero(totalp, sizeof *totalp); | |
109 | /* | |
110 | * Mark all objects as inactive. | |
111 | */ | |
112 | simple_unlock(&vm_object_list_lock); | |
113 | simple_lock(&vm_object_list_lock); | |
114 | object = (vm_object_t) queue_first(&vm_object_list); | |
115 | while (!queue_end(&vm_object_list, (queue_entry_t) object)) { | |
116 | object->flags &= ~OBJ_ACTIVE; | |
117 | object = (vm_object_t) queue_next(&object->object_list); | |
118 | } | |
119 | simple_unlock(&vm_object_list_lock); | |
120 | /* | |
121 | * Calculate process statistics. | |
122 | */ | |
123 | for (p = allproc; p != NULL; p = p->p_nxt) { | |
124 | if (p->p_flag & SSYS) | |
125 | continue; | |
126 | switch (p->p_stat) { | |
127 | case 0: | |
128 | continue; | |
129 | ||
130 | case SSLEEP: | |
131 | case SSTOP: | |
132 | if (p->p_flag & SLOAD) { | |
133 | if (p->p_pri <= PZERO) | |
134 | totalp->t_dw++; | |
135 | else if (p->p_slptime < maxslp) | |
136 | totalp->t_sl++; | |
137 | } else if (p->p_slptime < maxslp) | |
138 | totalp->t_sw++; | |
139 | if (p->p_slptime >= maxslp) | |
140 | continue; | |
141 | break; | |
142 | ||
143 | case SRUN: | |
144 | case SIDL: | |
145 | if (p->p_flag & SLOAD) | |
146 | totalp->t_rq++; | |
147 | else | |
148 | totalp->t_sw++; | |
149 | if (p->p_stat == SIDL) | |
150 | continue; | |
151 | break; | |
152 | } | |
153 | /* | |
154 | * Note active objects. | |
155 | */ | |
156 | paging = 0; | |
157 | for (map = &p->p_vmspace->vm_map, entry = map->header.next; | |
158 | entry != &map->header; entry = entry->next) { | |
159 | if (entry->is_a_map || entry->is_sub_map) | |
160 | continue; | |
161 | entry->object.vm_object->flags |= OBJ_ACTIVE; | |
162 | paging |= entry->object.vm_object->paging_in_progress; | |
163 | } | |
164 | if (paging) | |
165 | totalp->t_pw++; | |
166 | } | |
167 | /* | |
168 | * Calculate object memory usage statistics. | |
169 | */ | |
170 | simple_lock(&vm_object_list_lock); | |
171 | object = (vm_object_t) queue_first(&vm_object_list); | |
172 | while (!queue_end(&vm_object_list, (queue_entry_t) object)) { | |
173 | totalp->t_vm += num_pages(object->size); | |
174 | totalp->t_rm += object->resident_page_count; | |
175 | if (object->flags & OBJ_ACTIVE) { | |
176 | totalp->t_avm += num_pages(object->size); | |
177 | totalp->t_arm += object->resident_page_count; | |
178 | } | |
179 | if (object->ref_count > 1) { | |
180 | /* shared object */ | |
181 | totalp->t_vmshr += num_pages(object->size); | |
182 | totalp->t_rmshr += object->resident_page_count; | |
183 | if (object->flags & OBJ_ACTIVE) { | |
184 | totalp->t_avmshr += num_pages(object->size); | |
185 | totalp->t_armshr += object->resident_page_count; | |
186 | } | |
187 | } | |
188 | object = (vm_object_t) queue_next(&object->object_list); | |
189 | } | |
190 | totalp->t_free = cnt.v_free_count; | |
191 | } |