SRI-NOSC/ken/clock.c
#
#include "param.h"
#include "systm.h"
#include "user.h"
#include "proc.h"
#define UMODE 0170000
#ifdef FASTIME
extern int fastime;
#endif FASTIME
/*
* clock is called straight from
* the real time clock interrupt.
*
* Functions:
* reprime clock
* copy *switches to display
* implement callouts
* maintain user/system times
* do most of the work for alarm clock mechanism
* maintain date
* profile
* lightning bolt wakeup (every 4 sec)
* alarm clock signals
* jab the scheduler
*/
clock(dev, sp, r1, nps, r0, pc, ps)
{
register struct callo *p1, *p2;
register struct proc *pp;
int a;
/*
* restart clock
*/
*lks = 0115;
#ifdef FASTIME
fastime++;
#endif FASTIME
/*
* display register
*/
display();
/*
* callouts
* if none, just return
* else update first non-zero time
*/
if(callout[0].c_func == 0)
goto out;
p2 = &callout[0];
while(p2->c_time<=0 && p2->c_func!=0)
p2++;
p2->c_time--;
/*
* if ps is high, just return
*/
if((ps&0340) != 0)
goto out;
/*
* callout
*/
spl5();
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++;
}
}
/*
* lightning bolt time-out
* and time of day
*/
out:
if((ps&UMODE) == UMODE) {
#ifdef DPTIME /* double precision time keeping*/
if (++u.u_utime[1] == 0) /* JSK */
u.u_utime [0]++; /* JSK */
#endif DPTIME
#ifndef DPTIME
++u.u_utime;
#endif not DPTIME
if(u.u_prof[3])
incupc(pc, u.u_prof);
} else
#ifdef DPTIME /*double precision time keeping*/
if (++u.u_stime[1] == 0) /* JSK */
u.u_stime[0]++; /* JSK */
#endif DPTIME
#ifndef DPTIME
++u.u_stime;
#endif not DPTIME
pp = u.u_procp;
if(++pp->p_cpu == 0)
pp->p_cpu--;
if(++lbolt >= HZ) {
if((ps&0340) != 0)
return;
lbolt =- HZ;
if(++time[1] == 0)
++time[0];
spl1();
if((time[1]&03) == 0) {
runrun++;
wakeup(&lbolt);
}
for(pp = &proc[0]; pp < &proc[NPROC]; pp++)
if (pp->p_stat) {
if(pp->p_time != 127)
pp->p_time++;
/*
* code modifed 31Oct77 by JSK/RJB to
* make sleep faster
*/
if(pp->p_clktim) /* ALARM */
if(--pp->p_clktim == 0) { /* ALARM */
/*
* &pp->p_clktim is of mode ptr-to-int,
* so before it can be compared to
* pp->p_wchan (an int), the C compiler
* insists upon widening the latter
* before the compare. In the new V7
* compiler we will be able to cast it,
* but for now, we will have to make do
* with this crock. (a is also an int.)
*/
/* JSK/RJB */ if (pp->p_wchan == (a = &pp->p_clktim))
/* JSK/RJB */ wakeup (a);
/* JSK/RJB */ else
psignal(pp, SIGCLK); /* ALARM */
}
/* 8/10 approx (255-HZ)/255 */
a = (pp->p_cpu & 0377)*8/10;
if(a < 0)
a = 0;
if(a > 255)
a = 255;
pp->p_cpu = a;
if(pp->p_pri > PUSER)
setpri(pp);
}
if(runin!=0) {
runin = 0;
wakeup(&runin);
}
if((ps&UMODE) == UMODE) {
u.u_ar0 = &r0;
if(issig())
psig();
setpri(u.u_procp);
}
}
}
/*
* 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.
*/
timeout(fun, arg, tim)
{
register struct callo *p1, *p2;
register t;
int s;
t = tim;
s = PS->integ;
p1 = &callout[0];
spl7();
while(p1->c_func != 0 && p1->c_time <= t) {
t =- p1->c_time;
p1++;
}
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;
PS->integ = s;
}