SysIII/usr/src/uts/vax/os/clock.c
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/sysinfo.h"
#include "sys/callo.h"
#include "sys/dir.h"
#include "sys/user.h"
#include "sys/proc.h"
#include "sys/text.h"
#include "sys/psl.h"
#include "sys/var.h"
/*
* clock is called straight from
* the real time clock interrupt.
*
* Functions:
* implement callouts
* maintain user/system times
* maintain date
* profile
* alarm clock signals
* jab the scheduler
*/
#define PRF_ON 01
extern int prfstat;
clock(pc, ps)
caddr_t pc;
{
register struct callo *p1, *p2;
register struct proc *pp;
register a;
static short lticks;
extern caddr_t waitloc;
/*
* restart clock
*/
clkreld();
/*
* callouts
* if none, just continue
* else update first non-zero time
*/
if(callout[0].c_func == NULL)
goto out;
p2 = &callout[0];
while(p2->c_time<=0 && p2->c_func!=NULL)
p2++;
p2->c_time--;
/*
* if ps is high, just return
*/
if (BASEPRI(ps))
goto out;
/*
* callout
*/
if(callout[0].c_time <= 0) {
p1 = &callout[0];
while(p1->c_func != 0 && p1->c_time <= 0) {
(*p1->c_func)(p1->c_arg);
p1++;
}
p2 = &callout[0];
while(p2->c_func = p1->c_func) {
p2->c_time = p1->c_time;
p2->c_arg = p1->c_arg;
p1++;
p2++;
}
}
out:
if(prfstat & PRF_ON)
prfintr(pc, ps);
if (USERMODE(ps)) {
a = CPU_USER;
u.u_utime++;
if(u.u_prof.pr_scale)
addupc(pc, &u.u_prof, 1);
} else {
if (pc == waitloc) {
a = CPU_IDLE;
if (syswait.iowait)
sysinfo.wait[W_IO]++;
if (syswait.swap)
sysinfo.wait[W_SWAP]++;
if (syswait.physio)
sysinfo.wait[W_PIO]++;
} else
a = CPU_KERN;
u.u_stime++;
}
sysinfo.cpu[a]++;
pp = u.u_procp;
if(pp->p_stat==SRUN) {
u.u_mem += (unsigned)pp->p_size;
if(pp->p_textp) {
a = pp->p_textp->x_ccount;
if(a==0)
a++;
u.u_mem += pp->p_textp->x_size/a;
}
}
if(pp->p_cpu < 80)
pp->p_cpu++;
lbolt++; /* time in ticks */
if (--lticks <= 0) {
if (BASEPRI(ps))
return;
lticks += HZ;
++time;
runrun++;
for(pp = &proc[0]; pp < (struct proc *)v.ve_proc; pp++)
if (pp->p_stat) {
if(pp->p_time != 127)
pp->p_time++;
if(pp->p_clktim)
if(--pp->p_clktim == 0)
psignal(pp, SIGALRM);
pp->p_cpu >>= 1;
if(pp->p_pri >= PUSER) {
pp->p_pri = (pp->p_cpu>>1) + PUSER +
pp->p_nice - NZERO;
}
}
if(runin!=0) {
runin = 0;
setrun(&proc[0]);
}
}
}
/*
* timeout is called to arrange that fun(arg) is called in tim/HZ seconds.
* An entry is sorted into the callout structure.
* The time in each structure entry is the number of HZ's more
* than the previous entry. In this way, decrementing the
* first entry has the effect of updating all entries.
*
* The panic is there because there is nothing
* intelligent to be done if an entry won't fit.
*/
timeout(fun, arg, tim)
int (*fun)();
caddr_t arg;
{
register struct callo *p1, *p2;
register int t;
int s;
t = tim;
p1 = &callout[0];
s = spl7();
while(p1->c_func != 0 && p1->c_time <= t) {
t -= p1->c_time;
p1++;
}
if (p1 >= &callout[v.v_call-1])
panic("Timeout table overflow");
p1->c_time -= t;
p2 = p1;
while(p2->c_func != 0)
p2++;
while(p2 >= p1) {
(p2+1)->c_time = p2->c_time;
(p2+1)->c_func = p2->c_func;
(p2+1)->c_arg = p2->c_arg;
p2--;
}
p1->c_time = t;
p1->c_func = fun;
p1->c_arg = arg;
splx(s);
}
#define PDELAY (PZERO-1)
delay(ticks)
{
extern wakeup();
if (ticks<=0)
return;
timeout(wakeup, (caddr_t)u.u_procp+1, ticks);
sleep((caddr_t)u.u_procp+1, PDELAY);
}