@@ 17,12 17,14 @@ enum
{
OPERM = 0x3, /* mask of all permission types in open mode */
Nram = 512,
+ CacheSize = 20,
};
typedef struct SacPath SacPath;
typedef struct Sac Sac;
typedef struct SacHeader SacHeader;
typedef struct SacDir SacDir;
+typedef struct Cache Cache;
enum {
Magic = 0x5acf5,
@@ 64,6 66,13 @@ struct SacPath
int entry;
};
+struct Cache
+{
+ long block;
+ ulong age;
+ uchar *data;
+};
+
enum
{
Pexec = 1,
@@ 77,6 86,8 @@ enum
static uchar *data = SACMEM;
static int blocksize;
static Sac root;
+static Cache cache[CacheSize];
+static ulong cacheage;
static void sacdir(Chan *, SacDir*, char*);
static ulong getl(void *p);
@@ 91,6 102,9 @@ static void
sacinit(void)
{
SacHeader *hdr;
+ uchar *p;
+ int i;
+
print("sacinit\n");
hdr = (SacHeader*)data;
if(getl(hdr->magic) != Magic) {
@@ 99,6 113,13 @@ print("devsac: bad magic\n");
}
blocksize = getl(hdr->blocksize);
root.SacDir = *(SacDir*)(data + sizeof(SacHeader));
+ p = malloc(CacheSize*blocksize);
+ if(p == nil)
+ error("allocating cache");
+ for(i=0; i<CacheSize; i++) {
+ cache[i].data = p;
+ p += blocksize;
+ }
}
static Chan*
@@ 310,16 331,41 @@ static void
loadblock(void *buf, uchar *offset, int blocksize)
{
vlong block, n;
+ ulong age;
+ int i, j;
block = getv(offset);
if(block < 0) {
block = -block;
+ cacheage++;
+ // age has wraped
+ if(cacheage == 0) {
+ for(i=0; i<CacheSize; i++)
+ cache[i].age = 0;
+ }
+ j = 0;
+ age = cache[0].age;
+ for(i=0; i<CacheSize; i++) {
+ if(cache[i].age < age) {
+ age = cache[i].age;
+ j = i;
+ }
+ if(cache[i].block != block)
+ continue;
+ memmove(buf, cache[i].data, blocksize);
+ cache[i].age = cacheage;
+ return;
+ }
+
n = getv(offset+8);
if(n < 0)
n = -n;
n -= block;
if(unsac(buf, data+block, blocksize, n)<0)
panic("unsac failed!");
+ memmove(cache[j].data, buf, blocksize);
+ cache[j].age = cacheage;
+ cache[j].block = block;
} else {
memmove(buf, data+block, blocksize);
}
@@ 259,7 259,7 @@ confinit(void)
ulong pa;
conf.nmach = 1; /* processors */
- conf.nproc = 30; /* processes */
+ conf.nproc = 40; /* processes */
// hard wire for now
pa = 0xffd00000; // leave 1 Meg for kernel
@@ 80,7 80,7 @@ todset(vlong t, vlong delta, int n)
n = -delta;
if(delta > 0 && n > delta)
n = delta;
- delta /= n;
+ delta = delta/n;
tod.sstart = MACHP(0)->ticks;
tod.send = tod.sstart + n;
tod.delta = delta;
@@ 111,13 111,13 @@ todget(vlong *ticksp)
t = MACHP(0)->ticks;
if(t >= tod.send)
t = tod.send;
- tod.off += tod.delta*(t - tod.sstart);
+ tod.off = tod.off + tod.delta*(t - tod.sstart);
tod.sstart = t;
}
// convert to epoch
x = (diff * tod.multiplier) >> 31;
- x += tod.off;
+ x = x + tod.off;
// protect against overflows
if(diff > tod.hz){
@@ 159,7 159,7 @@ seconds(void)
int i;
x = todget(nil);
- x /= TODFREQ;
+ x = x/TODFREQ;
i = x;
return i;
}