Commit | Line | Data |
---|---|---|
7e827e79 | 1 | /* kern_clock.c 4.36 82/08/22 */ |
83be5fac BJ |
2 | |
3 | #include "../h/param.h" | |
4 | #include "../h/systm.h" | |
d9b8447e | 5 | #include "../h/dk.h" |
0a34b6fd | 6 | #include "../h/callout.h" |
83be5fac BJ |
7 | #include "../h/seg.h" |
8 | #include "../h/dir.h" | |
9 | #include "../h/user.h" | |
10 | #include "../h/proc.h" | |
11 | #include "../h/reg.h" | |
12 | #include "../h/psl.h" | |
13 | #include "../h/vm.h" | |
14 | #include "../h/buf.h" | |
15 | #include "../h/text.h" | |
95ce0d37 BJ |
16 | #include "../h/vlimit.h" |
17 | #include "../h/mtpr.h" | |
18 | #include "../h/clock.h" | |
e5a79c70 | 19 | #include "../h/cpu.h" |
72857acf | 20 | #include "../h/protosw.h" |
951c32fc SL |
21 | #include "../h/socket.h" |
22 | #include "../net/if.h" | |
c53dce5d RE |
23 | #ifdef MUSH |
24 | #include "../h/quota.h" | |
25 | #include "../h/share.h" | |
26 | #endif | |
83be5fac | 27 | |
738a68d6 | 28 | #include "bk.h" |
ec213dfb BJ |
29 | #include "dh.h" |
30 | #include "dz.h" | |
1fa9ff62 | 31 | #include "ps.h" |
6602c75b | 32 | |
83be5fac | 33 | /* |
f403d99f | 34 | * Hardclock is called straight from |
83be5fac | 35 | * the real time clock interrupt. |
f403d99f BJ |
36 | * We limit the work we do at real clock interrupt time to: |
37 | * reloading clock | |
38 | * decrementing time to callouts | |
39 | * recording cpu time usage | |
4512b9a4 | 40 | * modifying priority of current process |
f403d99f BJ |
41 | * arrange for soft clock interrupt |
42 | * kernel pc profiling | |
83be5fac | 43 | * |
964bcfb1 | 44 | * At software (softclock) interrupt time we: |
83be5fac | 45 | * implement callouts |
83be5fac | 46 | * maintain date |
83be5fac BJ |
47 | * lightning bolt wakeup (every second) |
48 | * alarm clock signals | |
49 | * jab the scheduler | |
f403d99f BJ |
50 | * |
51 | * On the vax softclock interrupts are implemented by | |
52 | * software interrupts. Note that we may have multiple softclock | |
53 | * interrupts compressed into one (due to excessive interrupt load), | |
54 | * but that hardclock interrupts should never be lost. | |
83be5fac | 55 | */ |
3484be37 BJ |
56 | #ifdef GPROF |
57 | extern int profiling; | |
58 | extern char *s_lowpc; | |
59 | extern u_long s_textsize; | |
60 | extern u_short *kcount; | |
2752c877 | 61 | #endif |
83be5fac | 62 | |
72857acf BJ |
63 | /* |
64 | * Protoslow is like lbolt, but for slow protocol timeouts, counting | |
65 | * up to (hz/PR_SLOWHZ), then causing a pfslowtimo(). | |
66 | * Protofast is like lbolt, but for fast protocol timeouts, counting | |
67 | * up to (hz/PR_FASTHZ), then causing a pffasttimo(). | |
68 | */ | |
69 | int protoslow; | |
70 | int protofast; | |
951c32fc | 71 | int ifnetslow; |
72857acf | 72 | |
260ea681 | 73 | /*ARGSUSED*/ |
f403d99f | 74 | hardclock(pc, ps) |
4512b9a4 | 75 | caddr_t pc; |
83be5fac | 76 | { |
0a34b6fd | 77 | register struct callout *p1; |
83be5fac | 78 | register struct proc *pp; |
f403d99f | 79 | register int s, cpstate; |
c53dce5d | 80 | extern double avenrun[]; |
83be5fac BJ |
81 | |
82 | /* | |
83 | * reprime clock | |
84 | */ | |
85 | clkreld(); | |
86 | ||
1fa9ff62 SL |
87 | #if NPS > 0 |
88 | /* | |
89 | * sync referesh of picture system | |
90 | */ | |
91 | psextsync(pc, ps); | |
92 | #endif | |
93 | ||
83be5fac | 94 | /* |
f403d99f | 95 | * update callout times |
83be5fac | 96 | */ |
c4710996 BJ |
97 | for (p1 = calltodo.c_next; p1 && p1->c_time <= 0; p1 = p1->c_next) |
98 | ; | |
99 | if (p1) | |
100 | p1->c_time--; | |
5da67d35 BJ |
101 | |
102 | /* | |
f403d99f | 103 | * Maintain iostat and per-process cpu statistics |
5da67d35 | 104 | */ |
83be5fac BJ |
105 | if (!noproc) { |
106 | s = u.u_procp->p_rssize; | |
107 | u.u_vm.vm_idsrss += s; | |
108 | if (u.u_procp->p_textp) { | |
109 | register int xrss = u.u_procp->p_textp->x_rssize; | |
110 | ||
111 | s += xrss; | |
112 | u.u_vm.vm_ixrss += xrss; | |
113 | } | |
114 | if (s > u.u_vm.vm_maxrss) | |
115 | u.u_vm.vm_maxrss = s; | |
0a34b6fd | 116 | if ((u.u_vm.vm_utime+u.u_vm.vm_stime+1)/hz > u.u_limit[LIM_CPU]) { |
39f2f769 BJ |
117 | psignal(u.u_procp, SIGXCPU); |
118 | if (u.u_limit[LIM_CPU] < INFINITY - 5) | |
119 | u.u_limit[LIM_CPU] += 5; | |
120 | } | |
83be5fac | 121 | } |
964bcfb1 BJ |
122 | /* |
123 | * Update iostat information. | |
124 | */ | |
83be5fac BJ |
125 | if (USERMODE(ps)) { |
126 | u.u_vm.vm_utime++; | |
127 | if(u.u_procp->p_nice > NZERO) | |
41888f16 BJ |
128 | cpstate = CP_NICE; |
129 | else | |
130 | cpstate = CP_USER; | |
83be5fac | 131 | } else { |
3484be37 BJ |
132 | #ifdef GPROF |
133 | int k = pc - s_lowpc; | |
134 | if (profiling < 2 && k < s_textsize) | |
135 | kcount[k / sizeof (*kcount)]++; | |
2752c877 | 136 | #endif |
41888f16 | 137 | cpstate = CP_SYS; |
ddb3ced5 SL |
138 | if (noproc) { |
139 | if ((ps&PSL_IPL) != 0) | |
140 | cpstate = CP_IDLE; | |
141 | } else | |
83be5fac BJ |
142 | u.u_vm.vm_stime++; |
143 | } | |
2d7d59e9 | 144 | cp_time[cpstate]++; |
f403d99f BJ |
145 | for (s = 0; s < DK_NDRIVE; s++) |
146 | if (dk_busy&(1<<s)) | |
147 | dk_time[s]++; | |
964bcfb1 BJ |
148 | /* |
149 | * Adjust priority of current process. | |
150 | */ | |
83be5fac BJ |
151 | if (!noproc) { |
152 | pp = u.u_procp; | |
dd808ba3 | 153 | pp->p_cpticks++; |
83be5fac BJ |
154 | if(++pp->p_cpu == 0) |
155 | pp->p_cpu--; | |
c53dce5d RE |
156 | #ifdef MUSH |
157 | pp->p_quota->q_cost += (pp->p_nice > NZERO ? | |
158 | (shconsts.sc_tic * ((2*NZERO)-pp->p_nice)) / NZERO : | |
159 | shconsts.sc_tic) * (((int)avenrun[0]+2)/3); | |
160 | #endif | |
16a64baa | 161 | if(pp->p_cpu % 4 == 0) { |
81263dba | 162 | (void) setpri(pp); |
83be5fac BJ |
163 | if (pp->p_pri >= PUSER) |
164 | pp->p_pri = pp->p_usrpri; | |
165 | } | |
166 | } | |
964bcfb1 BJ |
167 | /* |
168 | * Time moves on. | |
169 | */ | |
83be5fac | 170 | ++lbolt; |
72857acf BJ |
171 | |
172 | /* | |
173 | * Time moves on for protocols. | |
174 | */ | |
951c32fc | 175 | --protoslow; --protofast; --ifnetslow; |
72857acf | 176 | |
e5a79c70 | 177 | #if VAX780 |
964bcfb1 BJ |
178 | /* |
179 | * On 780's, impelement a fast UBA watcher, | |
180 | * to make sure uba's don't get stuck. | |
181 | */ | |
287d9996 | 182 | if (cpu == VAX_780 && panicstr == 0 && !BASEPRI(ps)) |
f403d99f BJ |
183 | unhang(); |
184 | #endif | |
964bcfb1 BJ |
185 | /* |
186 | * Schedule a software interrupt for the rest | |
187 | * of clock activities. | |
188 | */ | |
f403d99f BJ |
189 | setsoftclock(); |
190 | } | |
191 | ||
192 | /* | |
16a64baa BJ |
193 | * The digital decay cpu usage priority assignment is scaled to run in |
194 | * time as expanded by the 1 minute load average. Each second we | |
195 | * multiply the the previous cpu usage estimate by | |
196 | * nrscale*avenrun[0] | |
197 | * The following relates the load average to the period over which | |
198 | * cpu usage is 90% forgotten: | |
199 | * loadav 1 5 seconds | |
200 | * loadav 5 24 seconds | |
201 | * loadav 10 47 seconds | |
202 | * loadav 20 93 seconds | |
203 | * This is a great improvement on the previous algorithm which | |
204 | * decayed the priorities by a constant, and decayed away all knowledge | |
205 | * of previous activity in about 20 seconds. Under heavy load, | |
206 | * the previous algorithm degenerated to round-robin with poor response | |
207 | * time when there was a high load average. | |
964bcfb1 | 208 | */ |
b620b354 | 209 | #undef ave |
16a64baa BJ |
210 | #define ave(a,b) ((int)(((int)(a*b))/(b+1))) |
211 | int nrscale = 2; | |
212 | double avenrun[]; | |
964bcfb1 BJ |
213 | |
214 | /* | |
215 | * Constant for decay filter for cpu usage field | |
216 | * in process table (used by ps au). | |
f403d99f BJ |
217 | */ |
218 | double ccpu = 0.95122942450071400909; /* exp(-1/20) */ | |
219 | ||
c53dce5d RE |
220 | #ifdef MELB |
221 | /* | |
222 | * Automatic niceness rate & max constants | |
223 | */ | |
224 | #define MAXNICE (8 + NZERO) /* maximum auto nice value */ | |
225 | #define NFACT (40 * hz) /* nice++ every 40 secs cpu+sys time */ | |
226 | #endif | |
227 | ||
f403d99f BJ |
228 | /* |
229 | * Software clock interrupt. | |
964bcfb1 | 230 | * This routine runs at lower priority than device interrupts. |
f403d99f | 231 | */ |
260ea681 | 232 | /*ARGSUSED*/ |
f403d99f | 233 | softclock(pc, ps) |
4512b9a4 | 234 | caddr_t pc; |
f403d99f | 235 | { |
dee48a1b | 236 | register struct callout *p1; |
f403d99f BJ |
237 | register struct proc *pp; |
238 | register int a, s; | |
c4710996 BJ |
239 | caddr_t arg; |
240 | int (*func)(); | |
f403d99f BJ |
241 | |
242 | /* | |
287d9996 | 243 | * Perform callouts (but not after panic's!) |
f403d99f | 244 | */ |
c4710996 BJ |
245 | if (panicstr == 0) { |
246 | for (;;) { | |
247 | s = spl7(); | |
849fc3ee BJ |
248 | if ((p1 = calltodo.c_next) == 0 || p1->c_time > 0) { |
249 | splx(s); | |
c4710996 | 250 | break; |
849fc3ee | 251 | } |
c4710996 BJ |
252 | calltodo.c_next = p1->c_next; |
253 | arg = p1->c_arg; | |
254 | func = p1->c_func; | |
255 | p1->c_next = callfree; | |
256 | callfree = p1; | |
257 | (void) splx(s); | |
258 | (*func)(arg); | |
f403d99f BJ |
259 | } |
260 | } | |
261 | ||
262 | /* | |
263 | * Drain silos. | |
264 | */ | |
3b90686d | 265 | #if NDH > 0 |
f403d99f BJ |
266 | s = spl5(); dhtimer(); splx(s); |
267 | #endif | |
3b90686d | 268 | #if NDZ > 0 |
f403d99f BJ |
269 | s = spl5(); dztimer(); splx(s); |
270 | #endif | |
271 | ||
4512b9a4 BJ |
272 | /* |
273 | * If idling and processes are waiting to swap in, | |
274 | * check on them. | |
275 | */ | |
276 | if (noproc && runin) { | |
277 | runin = 0; | |
278 | wakeup((caddr_t)&runin); | |
279 | } | |
280 | ||
f403d99f | 281 | /* |
16a64baa | 282 | * Run paging daemon every 1/4 sec. |
f403d99f | 283 | */ |
0a34b6fd | 284 | if (lbolt % (hz/4) == 0) { |
83be5fac | 285 | vmpago(); |
16a64baa BJ |
286 | } |
287 | ||
288 | /* | |
289 | * Reschedule every 1/10 sec. | |
290 | */ | |
291 | if (lbolt % (hz/10) == 0) { | |
83be5fac | 292 | runrun++; |
f403d99f | 293 | aston(); |
83be5fac | 294 | } |
f403d99f | 295 | |
72857acf BJ |
296 | /* |
297 | * Run network slow and fast timeouts. | |
298 | */ | |
20bbf2f5 BJ |
299 | if (protofast <= 0) { |
300 | protofast = hz / PR_FASTHZ; | |
72857acf | 301 | pffasttimo(); |
20bbf2f5 BJ |
302 | } |
303 | if (protoslow <= 0) { | |
304 | protoslow = hz / PR_SLOWHZ; | |
72857acf | 305 | pfslowtimo(); |
20bbf2f5 | 306 | } |
951c32fc SL |
307 | if (ifnetslow <= 0) { |
308 | ifnetslow = hz / IFNET_SLOWHZ; | |
309 | if_slowtimo(); | |
310 | } | |
72857acf | 311 | |
f403d99f BJ |
312 | /* |
313 | * Lightning bolt every second: | |
314 | * sleep timeouts | |
315 | * process priority recomputation | |
316 | * process %cpu averaging | |
317 | * virtual memory metering | |
318 | * kick swapper if processes want in | |
319 | */ | |
0a34b6fd | 320 | if (lbolt >= hz) { |
287d9996 | 321 | /* |
964bcfb1 | 322 | * This doesn't mean much on VAX since we run at |
287d9996 BJ |
323 | * software interrupt time... if hardclock() |
324 | * calls softclock() directly, it prevents | |
325 | * this code from running when the priority | |
326 | * was raised when the clock interrupt occurred. | |
327 | */ | |
83be5fac BJ |
328 | if (BASEPRI(ps)) |
329 | return; | |
287d9996 BJ |
330 | |
331 | /* | |
332 | * If we didn't run a few times because of | |
333 | * long blockage at high ipl, we don't | |
334 | * really want to run this code several times, | |
335 | * so squish out all multiples of hz here. | |
336 | */ | |
ddb3ced5 SL |
337 | s = spl6(); |
338 | time += lbolt / hz; lbolt %= hz; | |
339 | splx(s); | |
287d9996 BJ |
340 | |
341 | /* | |
342 | * Wakeup lightning bolt sleepers. | |
343 | * Processes sleep on lbolt to wait | |
344 | * for short amounts of time (e.g. 1 second). | |
345 | */ | |
83be5fac | 346 | wakeup((caddr_t)&lbolt); |
287d9996 BJ |
347 | |
348 | /* | |
349 | * Recompute process priority and process | |
350 | * sleep() system calls as well as internal | |
351 | * sleeps with timeouts (tsleep() kernel routine). | |
352 | */ | |
353 | for (pp = proc; pp < procNPROC; pp++) | |
8418f526 | 354 | if (pp->p_stat && pp->p_stat!=SZOMB) { |
c53dce5d RE |
355 | #ifdef MUSH |
356 | /* | |
357 | * Charge process for memory in use | |
358 | */ | |
359 | if (pp->p_quota->q_uid) | |
360 | pp->p_quota->q_cost += | |
361 | shconsts.sc_click * pp->p_rssize; | |
362 | #endif | |
287d9996 BJ |
363 | /* |
364 | * Increase resident time, to max of 127 seconds | |
365 | * (it is kept in a character.) For | |
366 | * loaded processes this is time in core; for | |
367 | * swapped processes, this is time on drum. | |
368 | */ | |
369 | if (pp->p_time != 127) | |
83be5fac | 370 | pp->p_time++; |
287d9996 BJ |
371 | /* |
372 | * If process has clock counting down, and it | |
373 | * expires, set it running (if this is a tsleep()), | |
374 | * or give it an SIGALRM (if the user process | |
375 | * is using alarm signals. | |
376 | */ | |
377 | if (pp->p_clktim && --pp->p_clktim == 0) | |
378 | if (pp->p_flag & STIMO) { | |
379 | s = spl6(); | |
380 | switch (pp->p_stat) { | |
daac5944 | 381 | |
287d9996 BJ |
382 | case SSLEEP: |
383 | setrun(pp); | |
384 | break; | |
daac5944 | 385 | |
287d9996 BJ |
386 | case SSTOP: |
387 | unsleep(pp); | |
388 | break; | |
389 | } | |
390 | pp->p_flag &= ~STIMO; | |
391 | splx(s); | |
392 | } else | |
393 | psignal(pp, SIGALRM); | |
394 | /* | |
395 | * If process is blocked, increment computed | |
396 | * time blocked. This is used in swap scheduling. | |
397 | */ | |
398 | if (pp->p_stat==SSLEEP || pp->p_stat==SSTOP) | |
83be5fac BJ |
399 | if (pp->p_slptime != 127) |
400 | pp->p_slptime++; | |
287d9996 BJ |
401 | /* |
402 | * Update digital filter estimation of process | |
403 | * cpu utilization for loaded processes. | |
404 | */ | |
dd808ba3 BJ |
405 | if (pp->p_flag&SLOAD) |
406 | pp->p_pctcpu = ccpu * pp->p_pctcpu + | |
0a34b6fd | 407 | (1.0 - ccpu) * (pp->p_cpticks/(float)hz); |
287d9996 BJ |
408 | /* |
409 | * Recompute process priority. The number p_cpu | |
410 | * is a weighted estimate of cpu time consumed. | |
411 | * A process which consumes cpu time has this | |
412 | * increase regularly. We here decrease it by | |
16a64baa BJ |
413 | * a fraction based on load average giving a digital |
414 | * decay filter which damps out in about 5 seconds | |
415 | * when seconds are measured in time expanded by the | |
416 | * load average. | |
287d9996 BJ |
417 | * |
418 | * If a process is niced, then the nice directly | |
419 | * affects the new priority. The final priority | |
420 | * is in the range 0 to 255, to fit in a character. | |
421 | */ | |
dd808ba3 | 422 | pp->p_cpticks = 0; |
c53dce5d RE |
423 | #ifdef MUSH |
424 | a = ave((pp->p_cpu & 0377), avenrun[0]*nrscale) + | |
425 | pp->p_nice - NZERO + pp->p_quota->q_nice; | |
426 | #else | |
16a64baa BJ |
427 | a = ave((pp->p_cpu & 0377), avenrun[0]*nrscale) + |
428 | pp->p_nice - NZERO; | |
c53dce5d | 429 | #endif |
287d9996 | 430 | if (a < 0) |
83be5fac | 431 | a = 0; |
287d9996 | 432 | if (a > 255) |
83be5fac BJ |
433 | a = 255; |
434 | pp->p_cpu = a; | |
81263dba | 435 | (void) setpri(pp); |
287d9996 BJ |
436 | /* |
437 | * Now have computed new process priority | |
438 | * in p->p_usrpri. Carefully change p->p_pri. | |
439 | * A process is on a run queue associated with | |
440 | * this priority, so we must block out process | |
441 | * state changes during the transition. | |
442 | */ | |
83be5fac | 443 | s = spl6(); |
287d9996 | 444 | if (pp->p_pri >= PUSER) { |
83be5fac BJ |
445 | if ((pp != u.u_procp || noproc) && |
446 | pp->p_stat == SRUN && | |
447 | (pp->p_flag & SLOAD) && | |
448 | pp->p_pri != pp->p_usrpri) { | |
449 | remrq(pp); | |
450 | pp->p_pri = pp->p_usrpri; | |
451 | setrq(pp); | |
452 | } else | |
453 | pp->p_pri = pp->p_usrpri; | |
454 | } | |
455 | splx(s); | |
456 | } | |
287d9996 BJ |
457 | |
458 | /* | |
459 | * Perform virtual memory metering. | |
460 | */ | |
83be5fac | 461 | vmmeter(); |
287d9996 BJ |
462 | |
463 | /* | |
464 | * If the swap process is trying to bring | |
465 | * a process in, have it look again to see | |
466 | * if it is possible now. | |
467 | */ | |
468 | if (runin!=0) { | |
83be5fac BJ |
469 | runin = 0; |
470 | wakeup((caddr_t)&runin); | |
471 | } | |
287d9996 | 472 | |
83be5fac BJ |
473 | /* |
474 | * If there are pages that have been cleaned, | |
475 | * jolt the pageout daemon to process them. | |
476 | * We do this here so that these pages will be | |
477 | * freed if there is an abundance of memory and the | |
478 | * daemon would not be awakened otherwise. | |
479 | */ | |
480 | if (bclnlist != NULL) | |
481 | wakeup((caddr_t)&proc[2]); | |
287d9996 | 482 | |
c53dce5d RE |
483 | #ifdef MELB |
484 | /* | |
485 | * If a process was running, see if time to make it nicer | |
486 | */ | |
487 | if (!noproc) { | |
488 | pp = u.u_procp; | |
489 | if (pp->p_uid | |
490 | #ifdef MUSH | |
491 | && !(pp->p_flag & SLOGIN) | |
492 | #else | |
493 | /* this is definitely not good enough */ | |
494 | && (pp->p_pid != pp->p_pgrp || pp->p_ppid != 1) | |
495 | #endif | |
496 | && (u.u_vm.vm_utime + u.u_vm.vm_stime) > | |
497 | (pp->p_nice-NZERO+1)*NFACT | |
498 | && pp->p_nice >= NZERO | |
499 | && pp->p_nice < MAXNICE | |
500 | ) { | |
501 | pp->p_nice++; | |
502 | (void) setpri(pp); | |
503 | pp->p_pri = pp->p_usrpri; | |
504 | } | |
505 | } | |
506 | #else | |
287d9996 BJ |
507 | /* |
508 | * If the trap occurred from usermode, | |
509 | * then check to see if it has now been | |
510 | * running more than 10 minutes of user time | |
511 | * and should thus run with reduced priority | |
512 | * to give other processes a chance. | |
513 | */ | |
83be5fac BJ |
514 | if (USERMODE(ps)) { |
515 | pp = u.u_procp; | |
287d9996 BJ |
516 | if (pp->p_uid && pp->p_nice == NZERO && |
517 | u.u_vm.vm_utime > 600 * hz) | |
518 | pp->p_nice = NZERO+4; | |
81263dba | 519 | (void) setpri(pp); |
83be5fac | 520 | pp->p_pri = pp->p_usrpri; |
054016e1 | 521 | } |
c53dce5d | 522 | #endif |
83be5fac | 523 | } |
287d9996 BJ |
524 | /* |
525 | * If trapped user-mode, give it a profiling tick. | |
526 | */ | |
f403d99f BJ |
527 | if (USERMODE(ps) && u.u_prof.pr_scale) { |
528 | u.u_procp->p_flag |= SOWEUPC; | |
529 | aston(); | |
83be5fac | 530 | } |
83be5fac BJ |
531 | } |
532 | ||
533 | /* | |
964bcfb1 | 534 | * Timeout is called to arrange that |
0a34b6fd | 535 | * fun(arg) is called in tim/hz seconds. |
c4710996 | 536 | * An entry is linked into the callout |
964bcfb1 | 537 | * structure. The time in each structure |
0a34b6fd | 538 | * entry is the number of hz's more |
83be5fac BJ |
539 | * than the previous entry. |
540 | * In this way, decrementing the | |
541 | * first entry has the effect of | |
542 | * updating all entries. | |
543 | * | |
544 | * The panic is there because there is nothing | |
545 | * intelligent to be done if an entry won't fit. | |
546 | */ | |
547 | timeout(fun, arg, tim) | |
4512b9a4 BJ |
548 | int (*fun)(); |
549 | caddr_t arg; | |
83be5fac | 550 | { |
c4710996 | 551 | register struct callout *p1, *p2, *pnew; |
83be5fac BJ |
552 | register int t; |
553 | int s; | |
554 | ||
47477f34 BJ |
555 | /* DEBUGGING CODE */ |
556 | int ttrstrt(); | |
557 | ||
558 | if (fun == ttrstrt && arg == 0) | |
559 | panic("timeout ttrstr arg"); | |
560 | /* END DEBUGGING CODE */ | |
83be5fac | 561 | t = tim; |
83be5fac | 562 | s = spl7(); |
c4710996 BJ |
563 | pnew = callfree; |
564 | if (pnew == NULL) | |
565 | panic("timeout table overflow"); | |
566 | callfree = pnew->c_next; | |
567 | pnew->c_arg = arg; | |
568 | pnew->c_func = fun; | |
569 | for (p1 = &calltodo; (p2 = p1->c_next) && p2->c_time < t; p1 = p2) | |
570 | t -= p2->c_time; | |
571 | p1->c_next = pnew; | |
572 | pnew->c_next = p2; | |
573 | pnew->c_time = t; | |
574 | if (p2) | |
575 | p2->c_time -= t; | |
83be5fac BJ |
576 | splx(s); |
577 | } | |
1fa9ff62 | 578 | |
7e827e79 | 579 | #ifdef notdef |
1fa9ff62 SL |
580 | /* |
581 | * untimeout is called to remove a function timeout call | |
582 | * from the callout structure. | |
583 | */ | |
584 | untimeout (fun, arg) | |
585 | int (*fun)(); | |
586 | caddr_t arg; | |
587 | { | |
588 | ||
589 | register struct callout *p1, *p2; | |
590 | register int s; | |
591 | ||
592 | s = spl7(); | |
593 | for (p1 = &calltodo; (p2 = p1->c_next) != 0; p1 = p2) { | |
594 | if (p2->c_func == fun && p2->c_arg == arg) { | |
595 | if (p2->c_next) | |
596 | p2->c_next->c_time += p2->c_time; | |
597 | p1->c_next = p2->c_next; | |
598 | p2->c_next = callfree; | |
599 | callfree = p2; | |
600 | break; | |
601 | } | |
602 | } | |
603 | splx(s); | |
604 | } | |
7e827e79 | 605 | #endif |