BNELDIS=>NETLDISC
[unix-history] / usr / src / sys / kern / kern_clock.c
CommitLineData
81263dba 1/* kern_clock.c 3.5 %H% */
83be5fac
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/callo.h"
6#include "../h/seg.h"
7#include "../h/dir.h"
8#include "../h/user.h"
9#include "../h/proc.h"
10#include "../h/reg.h"
11#include "../h/psl.h"
12#include "../h/vm.h"
13#include "../h/buf.h"
14#include "../h/text.h"
15
16#define SCHMAG 9/10
17
18
19/*
20 * clock is called straight from
21 * the real time clock interrupt.
22 *
23 * Functions:
24 * implement callouts
25 * maintain user/system times
26 * maintain date
27 * profile
28 * lightning bolt wakeup (every second)
29 * alarm clock signals
30 * jab the scheduler
31 */
32#ifdef KPROF
525dfa77 33unsigned short kcount[20000];
83be5fac
BJ
34#endif
35
1c108279
BJ
36/*
37 * We handle regular calls to the dh and dz silo input processors
38 * without using timeouts to save a little time.
39 */
40int rintvl = 4; /* every 1/15'th of sec check receivers */
41int rcnt;
42
83be5fac
BJ
43clock(pc, ps)
44caddr_t pc;
45{
46 register struct callo *p1, *p2;
47 register struct proc *pp;
48 register int s;
49 int a;
50
51 /*
52 * reprime clock
53 */
54 clkreld();
55
56 /*
57 * callouts
58 * else update first non-zero time
59 */
60
61 if(callout[0].c_func == NULL)
62 goto out;
63 p2 = &callout[0];
64 while(p2->c_time<=0 && p2->c_func!=NULL)
65 p2++;
66 p2->c_time--;
67
68 /*
69 * if ps is high, just return
70 */
71 if (BASEPRI(ps))
72 goto out;
73
74 /*
75 * callout
76 */
77
78 if(callout[0].c_time <= 0) {
79 p1 = &callout[0];
80 while(p1->c_func != 0 && p1->c_time <= 0) {
81 (*p1->c_func)(p1->c_arg);
82 p1++;
83 }
84 p2 = &callout[0];
85 while(p2->c_func = p1->c_func) {
86 p2->c_time = p1->c_time;
87 p2->c_arg = p1->c_arg;
88 p1++;
89 p2++;
90 }
91 }
1c108279
BJ
92 if (rcnt >= rintvl) {
93 dhtimer();
94 dztimer();
95 rcnt = -1;
96 }
83be5fac
BJ
97
98 /*
99 * lightning bolt time-out
100 * and time of day
101 */
102out:
1c108279 103 ++rcnt;
83be5fac
BJ
104 if (!noproc) {
105 s = u.u_procp->p_rssize;
106 u.u_vm.vm_idsrss += s;
107 if (u.u_procp->p_textp) {
108 register int xrss = u.u_procp->p_textp->x_rssize;
109
110 s += xrss;
111 u.u_vm.vm_ixrss += xrss;
112 }
113 if (s > u.u_vm.vm_maxrss)
114 u.u_vm.vm_maxrss = s;
115 }
116 a = dk_busy&07;
117 if (USERMODE(ps)) {
118 u.u_vm.vm_utime++;
119 if(u.u_procp->p_nice > NZERO)
120 a += 8;
121 } else {
122 a += 16;
123 if (noproc)
124 a += 8;
125 else
126 u.u_vm.vm_stime++;
127 }
128 dk_time[a]++;
129 if (!noproc) {
130 pp = u.u_procp;
131 if(++pp->p_cpu == 0)
132 pp->p_cpu--;
133 if(pp->p_cpu % 16 == 0) {
81263dba 134 (void) setpri(pp);
83be5fac
BJ
135 if (pp->p_pri >= PUSER)
136 pp->p_pri = pp->p_usrpri;
137 }
138 }
139 ++lbolt;
140 if (lbolt % (HZ/4) == 0) {
141 vmpago();
142 runrun++;
143 }
144 if (lbolt >= HZ) {
145 if (BASEPRI(ps))
146 return;
147 lbolt -= HZ;
148 ++time;
81263dba 149 (void) spl1();
83be5fac
BJ
150 runrun++;
151 wakeup((caddr_t)&lbolt);
152 for(pp = &proc[0]; pp < &proc[NPROC]; pp++)
153 if (pp->p_stat && pp->p_stat<SZOMB) {
154 if(pp->p_time != 127)
155 pp->p_time++;
156 if(pp->p_clktim)
157 if(--pp->p_clktim == 0)
8add37d7
BJ
158 if (pp->p_flag & STIMO) {
159 s = spl6();
160 if (pp->p_stat == SSLEEP)
161 setrun(pp);
162 pp->p_flag &= ~STIMO;
163 splx(s);
164 } else
165 psignal(pp, SIGCLK);
83be5fac
BJ
166 if(pp->p_stat==SSLEEP||pp->p_stat==SSTOP)
167 if (pp->p_slptime != 127)
168 pp->p_slptime++;
169 if(pp->p_flag&SLOAD) {
170 ave(pp->p_aveflt, pp->p_faults, 5);
171 pp->p_faults = 0;
172 }
173 a = (pp->p_cpu & 0377)*SCHMAG + pp->p_nice - NZERO;
174 if(a < 0)
175 a = 0;
176 if(a > 255)
177 a = 255;
178 pp->p_cpu = a;
81263dba 179 (void) setpri(pp);
83be5fac
BJ
180 s = spl6();
181 if(pp->p_pri >= PUSER) {
182 if ((pp != u.u_procp || noproc) &&
183 pp->p_stat == SRUN &&
184 (pp->p_flag & SLOAD) &&
185 pp->p_pri != pp->p_usrpri) {
186 remrq(pp);
187 pp->p_pri = pp->p_usrpri;
188 setrq(pp);
189 } else
190 pp->p_pri = pp->p_usrpri;
191 }
192 splx(s);
193 }
194 vmmeter();
195 if(runin!=0) {
196 runin = 0;
197 wakeup((caddr_t)&runin);
198 }
199 /*
200 * If there are pages that have been cleaned,
201 * jolt the pageout daemon to process them.
202 * We do this here so that these pages will be
203 * freed if there is an abundance of memory and the
204 * daemon would not be awakened otherwise.
205 */
206 if (bclnlist != NULL)
207 wakeup((caddr_t)&proc[2]);
208#ifdef ERNIE
209 if (USERMODE(ps)) {
210 pp = u.u_procp;
211 if (pp->p_uid)
212 if (pp->p_nice == NZERO && u.u_vm.vm_utime > 600 * HZ)
213 pp->p_nice = NZERO+4;
81263dba 214 (void) setpri(pp);
83be5fac
BJ
215 pp->p_pri = pp->p_usrpri;
216 }
217#endif
218 }
219 if (USERMODE(ps)) {
220 /*
221 * We do this last since it
222 * may block on a page fault in user space.
223 */
224 if (u.u_prof.pr_scale)
225 addupc(pc, &u.u_prof, 1);
226 }
227#ifdef KPROF
228 else if (!noproc) {
525dfa77 229 register int indx = ((int)pc & 0x7fffffff) / 4;
83be5fac
BJ
230
231 if (indx >= 0 && indx < 20000)
525dfa77
BJ
232 if (++kcount[indx] == 0)
233 --kcount[indx];
83be5fac
BJ
234 }
235#endif
236}
237
238/*
239 * timeout is called to arrange that
240 * fun(arg) is called in tim/HZ seconds.
241 * An entry is sorted into the callout
242 * structure. The time in each structure
243 * entry is the number of HZ's more
244 * than the previous entry.
245 * In this way, decrementing the
246 * first entry has the effect of
247 * updating all entries.
248 *
249 * The panic is there because there is nothing
250 * intelligent to be done if an entry won't fit.
251 */
252timeout(fun, arg, tim)
253int (*fun)();
254caddr_t arg;
255{
256 register struct callo *p1, *p2;
257 register int t;
258 int s;
259
260 t = tim;
261 p1 = &callout[0];
262 s = spl7();
263 while(p1->c_func != 0 && p1->c_time <= t) {
264 t -= p1->c_time;
265 p1++;
266 }
267 if (p1 >= &callout[NCALL-1])
268 panic("Timeout table overflow");
269 p1->c_time -= t;
270 p2 = p1;
271 while(p2->c_func != 0)
272 p2++;
273 while(p2 >= p1) {
274 (p2+1)->c_time = p2->c_time;
275 (p2+1)->c_func = p2->c_func;
276 (p2+1)->c_arg = p2->c_arg;
277 p2--;
278 }
279 p1->c_time = t;
280 p1->c_func = fun;
281 p1->c_arg = arg;
282 splx(s);
283}