Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
ad0f93d2 KB |
2 | * Copyright (c) 1982, 1986, 1989, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
da7c5cc6 | 4 | * |
dbf0c423 | 5 | * %sccs.include.redist.c% |
c4ec2128 | 6 | * |
67e8af50 | 7 | * @(#)vm_meter.c 8.4 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
e3bf9f41 | 9 | |
3266719e KB |
10 | #include <sys/param.h> |
11 | #include <sys/proc.h> | |
12 | #include <sys/systm.h> | |
13 | #include <sys/kernel.h> | |
3266719e | 14 | #include <vm/vm.h> |
e7d26b7c | 15 | #include <sys/sysctl.h> |
e3bf9f41 | 16 | |
8378439f | 17 | struct loadavg averunnable; /* load average, of runnable procs */ |
e3bf9f41 | 18 | |
f1f42678 KM |
19 | int maxslp = MAXSLP; |
20 | int saferss = SAFERSS; | |
e3bf9f41 | 21 | |
3266719e | 22 | void |
e3bf9f41 BJ |
23 | vmmeter() |
24 | { | |
e3bf9f41 | 25 | |
f1f42678 | 26 | if (time.tv_sec % 5 == 0) |
8378439f | 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 | */ | |
3266719e | 46 | void |
2e9bff25 | 47 | loadav(avg) |
8378439f | 48 | register struct loadavg *avg; |
e3bf9f41 | 49 | { |
2e9bff25 KM |
50 | register int i, nrun; |
51 | register struct proc *p; | |
e3bf9f41 | 52 | |
cf5ef508 | 53 | for (nrun = 0, p = (struct proc *)allproc; p != NULL; p = p->p_next) { |
2e9bff25 KM |
54 | switch (p->p_stat) { |
55 | case SSLEEP: | |
cf5ef508 | 56 | if (p->p_priority > PZERO || p->p_slptime != 0) |
2e9bff25 KM |
57 | continue; |
58 | /* fall through */ | |
59 | case SRUN: | |
60 | case SIDL: | |
61 | nrun++; | |
62 | } | |
63 | } | |
e3bf9f41 | 64 | for (i = 0; i < 3; i++) |
8378439f KM |
65 | avg->ldavg[i] = (cexp[i] * avg->ldavg[i] + |
66 | nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT; | |
e3bf9f41 | 67 | } |
2e9bff25 | 68 | |
8378439f | 69 | /* |
a76b2369 | 70 | * Attributes associated with virtual memory. |
8378439f | 71 | */ |
04d563ec | 72 | vm_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) |
a76b2369 KM |
73 | int *name; |
74 | u_int namelen; | |
75 | void *oldp; | |
51cf4abc | 76 | size_t *oldlenp; |
a76b2369 | 77 | void *newp; |
51cf4abc | 78 | size_t newlen; |
04d563ec | 79 | struct proc *p; |
2e9bff25 KM |
80 | { |
81 | struct vmtotal vmtotals; | |
2e9bff25 | 82 | |
a76b2369 KM |
83 | /* all sysctl names at this level are terminal */ |
84 | if (namelen != 1) | |
85 | return (ENOTDIR); /* overloaded */ | |
86 | ||
87 | switch (name[0]) { | |
88 | case VM_LOADAVG: | |
89 | averunnable.fscale = FSCALE; | |
90 | return (sysctl_rdstruct(oldp, oldlenp, newp, &averunnable, | |
91 | sizeof(averunnable))); | |
92 | case VM_METER: | |
93 | vmtotal(&vmtotals); | |
94 | return (sysctl_rdstruct(oldp, oldlenp, newp, &vmtotals, | |
95 | sizeof(vmtotals))); | |
96 | default: | |
97 | return (EOPNOTSUPP); | |
98 | } | |
99 | /* NOTREACHED */ | |
2e9bff25 KM |
100 | } |
101 | ||
102 | /* | |
103 | * Calculate the current state of the system. | |
104 | * Done on demand from getkerninfo(). | |
105 | */ | |
3266719e | 106 | void |
2e9bff25 KM |
107 | vmtotal(totalp) |
108 | register struct vmtotal *totalp; | |
109 | { | |
110 | register struct proc *p; | |
111 | register vm_map_entry_t entry; | |
112 | register vm_object_t object; | |
113 | register vm_map_t map; | |
114 | int paging; | |
115 | ||
116 | bzero(totalp, sizeof *totalp); | |
117 | /* | |
118 | * Mark all objects as inactive. | |
119 | */ | |
2e9bff25 | 120 | simple_lock(&vm_object_list_lock); |
4fee7222 KM |
121 | for (object = vm_object_list.tqh_first; |
122 | object != NULL; | |
123 | object = object->object_list.tqe_next) | |
2e9bff25 | 124 | object->flags &= ~OBJ_ACTIVE; |
2e9bff25 KM |
125 | simple_unlock(&vm_object_list_lock); |
126 | /* | |
127 | * Calculate process statistics. | |
128 | */ | |
cf5ef508 KB |
129 | for (p = (struct proc *)allproc; p != NULL; p = p->p_next) { |
130 | if (p->p_flag & P_SYSTEM) | |
2e9bff25 KM |
131 | continue; |
132 | switch (p->p_stat) { | |
133 | case 0: | |
134 | continue; | |
135 | ||
136 | case SSLEEP: | |
137 | case SSTOP: | |
cf5ef508 KB |
138 | if (p->p_flag & P_INMEM) { |
139 | if (p->p_priority <= PZERO) | |
2e9bff25 KM |
140 | totalp->t_dw++; |
141 | else if (p->p_slptime < maxslp) | |
142 | totalp->t_sl++; | |
143 | } else if (p->p_slptime < maxslp) | |
144 | totalp->t_sw++; | |
145 | if (p->p_slptime >= maxslp) | |
146 | continue; | |
147 | break; | |
148 | ||
149 | case SRUN: | |
150 | case SIDL: | |
cf5ef508 | 151 | if (p->p_flag & P_INMEM) |
2e9bff25 KM |
152 | totalp->t_rq++; |
153 | else | |
154 | totalp->t_sw++; | |
155 | if (p->p_stat == SIDL) | |
156 | continue; | |
157 | break; | |
158 | } | |
159 | /* | |
160 | * Note active objects. | |
161 | */ | |
162 | paging = 0; | |
163 | for (map = &p->p_vmspace->vm_map, entry = map->header.next; | |
164 | entry != &map->header; entry = entry->next) { | |
31d5db89 MH |
165 | if (entry->is_a_map || entry->is_sub_map || |
166 | entry->object.vm_object == NULL) | |
2e9bff25 KM |
167 | continue; |
168 | entry->object.vm_object->flags |= OBJ_ACTIVE; | |
169 | paging |= entry->object.vm_object->paging_in_progress; | |
170 | } | |
171 | if (paging) | |
172 | totalp->t_pw++; | |
173 | } | |
174 | /* | |
175 | * Calculate object memory usage statistics. | |
176 | */ | |
177 | simple_lock(&vm_object_list_lock); | |
4fee7222 KM |
178 | for (object = vm_object_list.tqh_first; |
179 | object != NULL; | |
180 | object = object->object_list.tqe_next) { | |
2e9bff25 KM |
181 | totalp->t_vm += num_pages(object->size); |
182 | totalp->t_rm += object->resident_page_count; | |
183 | if (object->flags & OBJ_ACTIVE) { | |
184 | totalp->t_avm += num_pages(object->size); | |
185 | totalp->t_arm += object->resident_page_count; | |
186 | } | |
187 | if (object->ref_count > 1) { | |
188 | /* shared object */ | |
189 | totalp->t_vmshr += num_pages(object->size); | |
190 | totalp->t_rmshr += object->resident_page_count; | |
191 | if (object->flags & OBJ_ACTIVE) { | |
192 | totalp->t_avmshr += num_pages(object->size); | |
193 | totalp->t_armshr += object->resident_page_count; | |
194 | } | |
195 | } | |
2e9bff25 KM |
196 | } |
197 | totalp->t_free = cnt.v_free_count; | |
198 | } |