## diffname port/portclock.c 2000/1106
## diff -e /dev/null /n/emeliedump/2000/1106/sys/src/9/port/portclock.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
void (*kproftimer)(ulong);
typedef struct Clock0link Clock0link;
typedef struct Clock0link {
void (*clock)(void);
Clock0link* link;
} Clock0link;
static Clock0link *clock0link;
static Lock clock0lock;
void
addclock0link(void (*clock)(void))
{
Clock0link *lp;
if((lp = malloc(sizeof(Clock0link))) == 0){
print("addclock0link: too many links\n");
return;
}
ilock(&clock0lock);
lp->clock = clock;
lp->link = clock0link;
clock0link = lp;
iunlock(&clock0lock);
}
void
portclock(Ureg *ur)
{
Clock0link *lp;
m->ticks++;
if(m->proc)
m->proc->pc = ur->pc;
if(m->inclockintr)
return; /* interrupted ourself */
m->inclockintr = 1;
accounttime();
if(kproftimer != nil)
kproftimer(ur->pc);
if((active.machs&(1<<m->machno)) == 0)
return;
if(active.exiting && (active.machs & (1<<m->machno))) {
print("someone's exiting\n");
exit(0);
}
checkalarms();
if(m->machno == 0){
ilock(&clock0lock);
for(lp = clock0link; lp; lp = lp->link){
lp->clock();
splhi();
}
iunlock(&clock0lock);
}
m->inclockintr = 0;
if(up == 0 || up->state != Running)
return;
if(anyready())
sched();
/* user profiling clock */
if(userureg(ur)) {
(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1);
segclock(ur->pc);
}
}
.
## diffname port/portclock.c 2000/1206
## diff -e /n/emeliedump/2000/1106/sys/src/9/port/portclock.c /n/emeliedump/2000/1206/sys/src/9/port/portclock.c
64,69c
if(canlock(&clock0lock))
for(lp = clock0link; lp; lp = lp->link){
lp->clock();
splhi();
}
unlock(&clock0lock);
.
## diffname port/portclock.c 2001/0328
## diff -e /n/emeliedump/2000/1206/sys/src/9/port/portclock.c /n/emeliedump/2001/0328/sys/src/9/port/portclock.c
84a
m->inclockintr = 0;
.
75a
}
.
72,74c
if(up == 0 || up->state != Running){
m->inclockintr = 0;
.
## diffname port/portclock.c 2001/0331
## diff -e /n/emeliedump/2001/0328/sys/src/9/port/portclock.c /n/emeliedump/2001/0331/sys/src/9/port/portclock.c
85d
78a
splhi();
}
.
77c
if(anyready()){
.
75d
72,73c
m->inclockintr = 0;
if(up == 0 || up->state != Running)
.
## diffname port/portclock.c 2001/0527
## diff -e /n/emeliedump/2001/0331/sys/src/9/port/portclock.c /n/emeliedump/2001/0527/sys/src/9/port/portclock.c
72a
.
49a
kmapinval();
.
## diffname port/portclock.c 2001/0711
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/portclock.c /n/emeliedump/2001/0711/sys/src/9/port/portclock.c
88a
ulong
TK2MS(ulong ticks)
{
uvlong t, hz;
t = ticks;
hz = HZ;
t *= 1000L;
t = t/hz;
ticks = t;
return ticks;
}
.
## diffname port/portclock.c 2001/0905
## diff -e /n/emeliedump/2001/0711/sys/src/9/port/portclock.c /n/emeliedump/2001/0905/sys/src/9/port/portclock.c
89,101d
## diffname port/portclock.c 2002/0315
## diff -e /n/emeliedump/2001/0905/sys/src/9/port/portclock.c /n/emeliedump/2002/0315/sys/src/9/port/portclock.c
78c
// i.e. don't schedule an EDF process here!
if(!isedf(up) && anyready()){
.
7a
#include "../port/edf.h"
.
## diffname port/portclock.c 2002/0402
## diff -e /n/emeliedump/2002/0315/sys/src/9/port/portclock.c /n/emeliedump/2002/0402/sys/src/9/port/portclock.c
78,83d
8d
## diffname port/portclock.c 2002/0404
## diff -e /n/emeliedump/2002/0402/sys/src/9/port/portclock.c /n/emeliedump/2002/0404/sys/src/9/port/portclock.c
76a
// i.e. don't schedule an EDF process here!
if(!isedf(up) && anyready()){
sched();
splhi();
}
.
7a
#include "../port/edf.h"
.
## diffname port/portclock.c 2002/0410
## diff -e /n/emeliedump/2002/0404/sys/src/9/port/portclock.c /n/emeliedump/2002/0410/sys/src/9/port/portclock.c
89a
}
void
timerintr(Ureg *u, uvlong)
{
Timer *t;
Timers *tt;
uvlong when, now;
int callhzclock;
intrcount[m->machno]++;
callhzclock = 0;
tt = &timers[m->machno];
now = (uvlong)fastticks(nil);
ilock(tt);
while(t = tt->head){
when = t->when;
if(when > now){
iunlock(tt);
timerset(when);
if(callhzclock)
hzclock(u);
return;
}
tt->head = t->next;
fcallcount[m->machno]++;
iunlock(tt);
if (t->f){
(*t->f)(u, t);
splhi();
} else
callhzclock++;
ilock(tt);
if(t->period){
t->when += t->period;
if (t->when <= now)
t->when = now + t->period;
tadd(tt, t);
}
}
iunlock(tt);
}
uvlong hzperiod;
void
timersinit(void)
{
Timer *t;
hzperiod = ms2fastticks(1000/HZ);
t = smalloc(sizeof(*t));
t->period = hzperiod;
t->f = nil;
timeradd(t);
}
void
addclock0link(void (*f)(void))
{
Timer *nt;
/* Synchronize this to hztimer: reduces # of interrupts */
nt = malloc(sizeof(Timer));
nt->when = 0;
if (hzperiod == 0)
hzperiod = ms2fastticks(1000/HZ);
nt->period = hzperiod;
nt->f = (void (*)(Ureg*, Timer*))f;
ilock(&timers[0]);
tadd(&timers[0], nt);
/* no need to restart timer:
* this one's synchronized with hztimer which is already running
*/
iunlock(&timers[0]);
}
void
clockintrsched(void)
{
.
80c
if(anyready() && !isedf(up)){
.
65,72d
49a
if(m->flushmmu){
if(up)
flushmmu();
m->flushmmu = 0;
}
.
41a
tt = &timers[m->machno];
ilock(tt);
when = tadd(tt, nt);
if (when)
timerset(when);
iunlock(tt);
}
void
timerdel(Timer *dt)
{
Timer *t, **last;
Timers *tt;
tt = &timers[m->machno];
ilock(tt);
for(last = &tt->head; t = *last; last = &t->next){
if(t == dt){
*last = t->next;
break;
}
}
if (last == &tt->head && tt->head)
timerset(tt->head->when);
iunlock(tt);
}
void
hzclock(Ureg *ur)
{
.
40c
Timers *tt;
uvlong when;
.
38c
timeradd(Timer *nt)
.
36a
/* add of modify a timer */
.
30,34c
if(nt->when == 0){
/* Try to synchronize periods to reduce # of interrupts */
assert(nt->period);
if(pt)
nt->when = pt->when;
else
nt->when = (uvlong)fastticks(nil) + nt->period;
}
for(last = &tt->head; t = *last; last = &t->next){
if(t->when > nt->when)
break;
}
nt->next = *last;
*last = nt;
if (last == &tt->head)
return nt->when;
else
return 0;
.
26,28c
pt = nil;
for(last = &tt->head; t = *last; last = &t->next){
if(t == nt){
*last = t->next;
break;
}
if (t->period == nt->period)
pt = t;
.
24c
Timer *t, **last, *pt;
.
21,22c
ulong intrcount[MAXMACH];
ulong fcallcount[MAXMACH];
static uvlong
tadd(Timers *tt, Timer *nt)
.
18,19c
static Timers timers[MAXMACH];
.
12,16c
struct Timers
{
Lock;
Timer *head;
};
.
10c
typedef struct Timers Timers;
.
8d
## diffname port/portclock.c 2002/0412
## diff -e /n/emeliedump/2002/0410/sys/src/9/port/portclock.c /n/emeliedump/2002/0412/sys/src/9/port/portclock.c
130c
/* i.e. don't deschedule an EDF process here! */
.
## diffname port/portclock.c 2002/0413
## diff -e /n/emeliedump/2002/0412/sys/src/9/port/portclock.c /n/emeliedump/2002/0413/sys/src/9/port/portclock.c
218,222d
193c
t = malloc(sizeof(*t));
t->when = 0;
.
181a
m->inclockintr = 0;
.
162a
m->inclockintr = 0;
.
154c
now = fastticks(nil);
.
150a
if(m->inclockintr)
return;
m->inclockintr = 1;
.
99,102d
## diffname port/portclock.c 2002/0414
## diff -e /n/emeliedump/2002/0413/sys/src/9/port/portclock.c /n/emeliedump/2002/0414/sys/src/9/port/portclock.c
177,178d
## diffname port/portclock.c 2002/0416
## diff -e /n/emeliedump/2002/0414/sys/src/9/port/portclock.c /n/emeliedump/2002/0416/sys/src/9/port/portclock.c
181d
163d
147,150d
121,122d
## diffname port/portclock.c 2002/0704
## diff -e /n/emeliedump/2002/0416/sys/src/9/port/portclock.c /n/emeliedump/2002/0704/sys/src/9/port/portclock.c
125c
if(anyready() && !edf->isedf(up)){
.
## diffname port/portclock.c 2002/0710
## diff -e /n/emeliedump/2002/0704/sys/src/9/port/portclock.c /n/emeliedump/2002/0710/sys/src/9/port/portclock.c
210a
}
/*
* This tk2ms avoids overflows that the macro version is prone to.
* It is a LOT slower so shouldn't be used if you're just converting
* a delta.
*/
ulong
tk2ms(ulong ticks)
{
uvlong t, hz;
t = ticks;
hz = HZ;
t *= 1000L;
t = t/hz;
ticks = t;
return ticks;
}
ulong
ms2tk(ulong ms)
{
/* avoid overflows at the cost of precision */
if(ms >= 1000000000/HZ)
return (ms/1000)*HZ;
return (ms*HZ+500)/1000;
.
173a
intimer = 0;
.
156a
intimer = 0;
.
144a
if(intimer){
print("!");
return;
}
intimer = 1;
.
143a
static int intimer;
.
## diffname port/portclock.c 2002/0711
## diff -e /n/emeliedump/2002/0710/sys/src/9/port/portclock.c /n/emeliedump/2002/0711/sys/src/9/port/portclock.c
182d
164d
161a
m->splpc = pc; /* for kernel profiling */
.
146,150c
pc = m->splpc; /* remember last splhi pc for kernel profiling */
.
144c
ulong pc;
static int sofar;
.
## diffname port/portclock.c 2002/0928
## diff -e /n/emeliedump/2002/0711/sys/src/9/port/portclock.c /n/emeliedump/2002/0928/sys/src/9/port/portclock.c
205,207c
if (ms == 0)
ms = 1000/HZ;
nt->period = ms2fastticks(ms);
.
198c
addclock0link(void (*f)(void), int ms)
.
34a
}
.
33c
if (t->period == nt->period){
/* look for another timer at same frequency for combining */
.
29a
/* timer's changing, remove it before putting it back on */
.
## diffname port/portclock.c 2003/0122
## diff -e /n/emeliedump/2002/0928/sys/src/9/port/portclock.c /n/emeliedump/2003/0122/sys/src/9/port/portclock.c
161a
iunlock(tt);
.
160d
## diffname port/portclock.c 2003/0226
## diff -e /n/emeliedump/2003/0122/sys/src/9/port/portclock.c /n/emeliedump/2003/0226/sys/src/9/port/portclock.c
127,128c
if(up->fixedpri){
/* fixed priority processes are only preempted by
* higher piority processes.
*/
if(anyhigher())
callsched = 1;
} else {
/* floating priority processes are are preempted
* by all sorts of things.
*/
if(anyready() && !edf->isedf(up))
callsched = 1;
}
if(callsched){
.
97a
int callsched;
.
## diffname port/portclock.c 2003/0228
## diff -e /n/emeliedump/2003/0226/sys/src/9/port/portclock.c /n/emeliedump/2003/0228/sys/src/9/port/portclock.c
151a
hzsched(); /* in proc.c */
.
148c
if(userureg(ur)){
.
129,146d
98,99d
## diffname port/portclock.c 2003/0406
## diff -e /n/emeliedump/2003/0228/sys/src/9/port/portclock.c /n/emeliedump/2003/0406/sys/src/9/port/portclock.c
204c
if(ms == 0)
.
166c
if(t->f){
.
90c
if(last == &tt->head && tt->head)
.
71c
if(when)
.
55c
if(last == &tt->head)
.
34c
if(t->period == nt->period){
.
## diffname port/portclock.c 2003/0409
## diff -e /n/emeliedump/2003/0406/sys/src/9/port/portclock.c /n/emeliedump/2003/0409/sys/src/9/port/portclock.c
98a
if((m->ticks % 10000) == 0){
extern int allints[];
int i;
for(i=0; i < 32; i++)
print("[%d] %d\n", i, allints[i]);
}
.
## diffname port/portclock.c 2003/0410
## diff -e /n/emeliedump/2003/0409/sys/src/9/port/portclock.c /n/emeliedump/2003/0410/sys/src/9/port/portclock.c
99,104d
|