|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4319 (0x10df)
Types: TextFile
Notes: UNIX file
Names: »clock.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »sys/coh/clock.c«
/* (-lgl
* The information contained herein is a trade secret of Mark Williams
* Company, and is confidential information. It is provided under a
* license agreement, and may be copied or disclosed only under the
* terms of that agreement. Any reproduction or disclosure of this
* material without the express written authorization of Mark Williams
* Company or persuant to the license agreement is unlawful.
*
* COHERENT Version 0.7.3
* Copyright (c) 1982, 1983, 1984.
* An unpublished work by Mark Williams Company, Chicago.
* All rights reserved.
-lgl) */
/*
* Coherent.
* Clock.
* The clock comes in two parts. There is the routine `clock' which
* gets called every tick at high priority. It does the minimum it
* can and returns as soon as possible. The second routine, `stand',
* gets called whenever we are about to return from an interrupt to
* user mode a low priority. It can look at flags that the clock set
* and do the things the clock really wanted to do but didn't have time.
* Stand is truly the kernel of the system.
*/
#include <coherent.h>
#include <con.h>
#include <proc.h>
#include <sched.h>
#include <stat.h>
#include <timeout.h>
#include <uproc.h>
#include <mdata.h>
/*
* This routine is called once every tick (1/HZ seconds).
* It gets called with the programme counter that was interrupted
* a flag telling whether we were in user or kernel mode and the
* previous priority we were in.
*/
clock(pc, umode)
vaddr_t pc;
{
register PROC *pp;
/*
* Ignore clock interrupts till we are ready.
*/
if (batflag == 0)
return;
/*
* Update timers. Decrement time slice.
*/
utimer += 1;
timer.t_tick += 1;
timl.t_tinc -= 1;
quantum -= 1;
/*
* Give processes their schedule values per tick.
*/
if (procq.p_lforw->p_cval > CVCLOCK) {
procq.p_lforw->p_cval -= CVCLOCK;
procq.p_cval += CVCLOCK;
}
/*
* Tax current process and update his times.
*/
pp = SELF;
pp->p_cval >>= 1;
if (umode == 0)
pp->p_stime++;
else {
pp->p_utime++;
u.u_ppc = pc;
}
}
/*
* Do everything the clock wanted to do but couldn't as it would have
* taken too long.
* Also perform any system bookkeeping required at regular intervals.
*/
stand()
{
int s;
u.u_error = 0;
/*
* Update the clock.
*/
while (timer.t_tick >= HZ) {
timer.t_time++;
timer.t_tick -= HZ;
alcflag = 1;
outflag = 1;
}
/*
* Check expiration of quantum.
*/
if (quantum <= 0) {
quantum = 0;
disflag = 1;
}
/*
* Sound off alarms if needed.
*/
if (alcflag) {
s = sphi();
if (!locked(pnxgate)) {
register PROC *pp;
alcflag = 0;
pp = &procq;
while ((pp=pp->p_nforw) != &procq)
if (pp->p_alarm!=0 && --pp->p_alarm==0)
sendsig(SIGALRM, pp);
}
spl(s);
}
/*
* Check the timer queue if necessary.
*/
if (timl.t_tinc <= 0) {
register TIM *tp;
register int (*tf)();
dold_t dold;
s = sphi();
dsave(dold);
while (timl.t_tinc <= 0) {
if ((tp = timl.t_next) == NULL) {
timl.t_tinc = MAXINT;
break;
}
drest(timl.t_dmap);
timl.t_next = tp->t_next;
dcopy(timl.t_dmap, tp->t_dmap);
timl.t_tinc += tp->t_tinc;
tf = tp->t_func;
tp->t_func = NULL;
spl(s);
(*tf)(tp->t_farg);
sphi();
}
drest(dold);
spl(s);
}
/*
* Timeout any devices.
*/
if (outflag) {
register int n;
outflag = 0;
for (n=0; n<drvn; n++) {
if (drvl[n].d_time == 0)
continue;
s = sphi();
dtime((dev_t)makedev(n, 0));
spl(s);
}
}
/*
* Do profiling.
*/
if (u.u_pscale != 0) {
register unsigned p;
register vaddr_t a;
p = u.u_pscale;
a = (int *)u.u_pbase +
pscale(u.u_ppc-u.u_pofft, p/sizeof (int));
if (a < u.u_pbend)
putuwd(a, getuwd(a)+1);
}
/*
* Check for signals and execute them.
*/
if (SELF->p_ssig)
actvsig();
/*
* Should we dispatch?
*/
if ((SELF->p_flags&PFDISP) != 0) {
SELF->p_flags &= ~PFDISP;
disflag = 1;
wakeup((char *)&stimer);
}
#ifdef QWAKEUP
/*
* Dispatch pending wakeups.
*/
while (ntowake)
wakeup2();
#endif
/*
* Redispatch.
* This used to be a function call in tsave,
* expanded in line here.
*/
if (disflag) {
register PROC *pp;
#ifndef QWAKEUP
s=sphi();
#endif
if ((pp=SELF)!=iprocp)
setrun(pp);
dispatch();
#ifndef QWAKEUP
spl(s);
#endif
}
}