M pc/archgeneric.c => pc/archgeneric.c +1 -7
@@ 205,7 205,7 @@ archinit(void)
coherence = wbflush;
}
-static uvlong fasthz;
+extern uvlong fasthz;
void
cycletimerinit(void)
@@ 228,9 228,3 @@ cycletimer(uvlong *hz)
*hz = fasthz;
return tsc;
}
-
-uvlong
-fastticks(uvlong *hz)
-{
- return (*arch->fastclock)(hz);
-}
M pc/clock.c => pc/clock.c +28 -0
@@ 17,6 17,11 @@ typedef struct Clock0link {
static Clock0link *clock0link;
static Lock clock0lock;
+/* for fast clock */
+static vlong fastoff;
+static vlong fastsecs;
+ uvlong fasthz;
+
void
addclock0link(void (*clock)(void))
{
@@ 96,3 101,26 @@ microdelay(int microsecs)
aamloop(microsecs);
}
+vlong
+fastticks(uvlong *hz)
+{
+ return (*arch->fastclock)(hz) + fastoff;
+}
+
+void
+syncfastticks(vlong secs)
+{
+ vlong x, ofastoff;
+ vlong err, deltat;
+
+ /* set new offset */
+ x = (*arch->fastclock)(nil);
+ ofastoff = fastoff;
+ fastoff = secs*fasthz - x;
+
+ /* calculate first order diversion rate */
+ err = fastoff - ofastoff;
+ deltat = secs - fastsecs;
+ fastsecs = secs;
+ deltat *= fasthz;
+}
M pc/devrtc.c => pc/devrtc.c +41 -28
@@ 38,7 38,6 @@ struct Rtc
int year;
};
-QLock rtclock; /* mutex on clock operations */
enum{
Qrtc = 1,
@@ 140,7 139,7 @@ _rtctime(void)
return rtc2sec(&rtc);
}
-static Lock rtlock;
+static Lock nvrtlock;
long
rtctime(void)
@@ 148,7 147,7 @@ rtctime(void)
int i;
long t, ot;
- ilock(&rtlock);
+ ilock(&nvrtlock);
/* loop till we get two reads in a row the same */
t = _rtctime();
@@ 160,7 159,7 @@ rtctime(void)
}
if(i == 100) print("we are boofheads\n");
- iunlock(&rtlock);
+ iunlock(&nvrtlock);
return t;
}
@@ 169,7 168,7 @@ static long
rtcread(Chan* c, void* buf, long n, vlong off)
{
ulong t;
- char *a;
+ char *a, *start;
ulong offset = off;
if(c->qid.path & CHDIR)
@@ 177,26 176,33 @@ rtcread(Chan* c, void* buf, long n, vlong off)
switch(c->qid.path){
case Qrtc:
- qlock(&rtclock);
t = rtctime();
- qunlock(&rtclock);
n = readnum(offset, buf, n, t, 12);
return n;
case Qnvram:
- a = buf;
- if(waserror()){
- qunlock(&rtclock);
- nexterror();
- }
- qlock(&rtclock);
+ if(n == 0)
+ return 0;
+ if(n > Nvsize)
+ n = Nvsize;
+ a = start = smalloc(n);
+
+ ilock(&nvrtlock);
for(t = offset; t < offset + n; t++){
if(t >= Nvsize)
break;
outb(Paddr, Nvoff+t);
*a++ = inb(Pdata);
}
- qunlock(&rtclock);
+ iunlock(&nvrtlock);
+
+ if(waserror()){
+ free(start);
+ nexterror();
+ }
+ memmove(buf, start, t - offset);
poperror();
+
+ free(start);
return t - offset;
}
error(Ebadarg);
@@ 209,7 215,7 @@ static long
rtcwrite(Chan* c, void* buf, long n, vlong off)
{
int t;
- char *a;
+ char *a, *start;
Rtc rtc;
ulong secs;
uchar bcdclock[Nbcd];
@@ 248,30 254,39 @@ rtcwrite(Chan* c, void* buf, long n, vlong off)
/*
* write the clock
*/
- qlock(&rtclock);
+ ilock(&nvrtlock);
outb(Paddr, Seconds); outb(Pdata, bcdclock[0]);
outb(Paddr, Minutes); outb(Pdata, bcdclock[1]);
outb(Paddr, Hours); outb(Pdata, bcdclock[2]);
outb(Paddr, Mday); outb(Pdata, bcdclock[3]);
outb(Paddr, Month); outb(Pdata, bcdclock[4]);
outb(Paddr, Year); outb(Pdata, bcdclock[5]);
- qunlock(&rtclock);
+ iunlock(&nvrtlock);
return n;
case Qnvram:
- a = buf;
+ if(n == 0)
+ return 0;
+ if(n > Nvsize)
+ n = Nvsize;
+
+ start = a = smalloc(n);
if(waserror()){
- qunlock(&rtclock);
+ free(start);
nexterror();
}
- qlock(&rtclock);
+ memmove(a, buf, n);
+ poperror();
+
+ ilock(&nvrtlock);
for(t = offset; t < offset + n; t++){
if(t >= Nvsize)
break;
outb(Paddr, Nvoff+t);
outb(Pdata, *a++);
}
- qunlock(&rtclock);
- poperror();
+ iunlock(&nvrtlock);
+
+ free(start);
return t - offset;
}
error(Ebadarg);
@@ 414,17 429,15 @@ sec2rtc(ulong secs, Rtc *rtc)
return;
}
-static Lock nvramlock;
-
uchar
nvramread(int addr)
{
uchar data;
- lock(&nvramlock);
+ ilock(&nvrtlock);
outb(Paddr, addr);
data = inb(Pdata);
- unlock(&nvramlock);
+ iunlock(&nvrtlock);
return data;
}
@@ 432,8 445,8 @@ nvramread(int addr)
void
nvramwrite(int addr, uchar data)
{
- lock(&nvramlock);
+ ilock(&nvrtlock);
outb(Paddr, addr);
outb(Pdata, data);
- unlock(&nvramlock);
+ iunlock(&nvrtlock);
}
M pc/main.c => pc/main.c +3 -3
@@ 431,7 431,7 @@ confinit(void)
* 4MB on the first Image chunk allocation.
*/
if(conf.npage*BY2PG < 16*MB)
- poolsetparam("Image", 0, 0, 4*1024*1024);
+ poolsetparam("Image", 0, 0, 4*1024*1024, nil);
}
conf.upages = conf.npage - kpages;
conf.ialloc = (kpages/2)*BY2PG;
@@ 447,14 447,14 @@ confinit(void)
+ conf.nimage*sizeof(Image)
+ conf.nswap
+ conf.nswppo*sizeof(Page);
- poolsetparam("Main", kpages, 0, 0);
+ poolsetparam("Main", kpages, 0, 0, nil);
if(!cpuserver){
/*
* give terminals lots of image memory, too; the dynamic
* allocation will balance the load properly, hopefully.
* be careful with 32-bit overflow.
*/
- poolsetparam("Image", kpages, 0, 0);
+ poolsetparam("Image", kpages, 0, 0, nil);
}
}
M port/portfns.h => port/portfns.h +3 -1
@@ 91,7 91,7 @@ void error(char*);
long execregs(ulong, ulong, ulong);
void exhausted(char*);
void exit(int);
-uvlong fastticks(uvlong*);
+vlong fastticks(uvlong*);
int fault(ulong, int);
void fdclose(int, int);
Chan* fdtochan(int, int, int, int);
@@ 183,6 183,7 @@ void pgrpcpy(Pgrp*, Pgrp*);
void pgrpnote(ulong, char*, long, int);
Pgrp* pgrptab(int);
void pio(Segment *, ulong, ulong, Page **);
+void poolsetparam(char*, ulong, int, int, void (*)(void*, void*));
void poolsummary(void);
#define poperror() up->nerrlab--
int postnote(Proc*, int, char*, int);
@@ 294,6 295,7 @@ void srvrecover(Chan*, Chan*);
int swapcount(ulong);
int swapfull(void);
void swapinit(void);
+void syncfastticks(vlong);
Block* trimblock(Block*, int, int);
void tsleep(Rendez*, int (*)(void*), void*, int);
void unbreak(Proc*);