From 78a039249b0d7d691e995b3bfe6af86f3096ab4e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 13 Apr 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-04-13 --- bitsy/devsac.c | 592 ------------------------------------------ bitsy/unsac.c | 627 --------------------------------------------- pc/devarch.c | 3 + pc/fns.h | 3 +- pc/l.s | 15 ++ port/devloopback.c | 1 - port/devtls.c | 4 +- port/nulledf.c | 10 +- port/portclock.c | 20 +- port/proc.c | 1 + port/taslock.c | 13 +- 11 files changed, 46 insertions(+), 1243 deletions(-) delete mode 100644 bitsy/devsac.c delete mode 100644 bitsy/unsac.c diff --git a/bitsy/devsac.c b/bitsy/devsac.c deleted file mode 100644 index ca5048c1750a26cb350616e8068be38d6a35b653..0000000000000000000000000000000000000000 --- a/bitsy/devsac.c +++ /dev/null @@ -1,592 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -/* - * definitions from the old 9P. we need these because sac files - * are encoded using the old definitions. - */ -#define NAMELEN 28 - -#define CHDIR 0x80000000 /* mode bit for directories */ -#define CHAPPEND 0x40000000 /* mode bit for append only files */ -#define CHEXCL 0x20000000 /* mode bit for exclusive use files */ -#define CHMOUNT 0x10000000 /* mode bit for mounted channel */ -#define CHREAD 0x4 /* mode bit for read permission */ -#define CHWRITE 0x2 /* mode bit for write permission */ -#define CHEXEC 0x1 /* mode bit for execute permission */ - -enum -{ - OPERM = 0x3, /* mask of all permission types in open mode */ - Nram = 512, - CacheSize = 20, - OffsetSize = 4, /* size in bytes of an offset */ -}; - -typedef struct SacPath SacPath; -typedef struct Sac Sac; -typedef struct SacHeader SacHeader; -typedef struct SacDir SacDir; -typedef struct Cache Cache; - -enum { - Magic = 0x5acf5, -}; - -struct SacDir -{ - char name[NAMELEN]; - char uid[NAMELEN]; - char gid[NAMELEN]; - uchar qid[4]; - uchar mode[4]; - uchar atime[4]; - uchar mtime[4]; - uchar length[8]; - uchar blocks[8]; -}; - -struct SacHeader -{ - uchar magic[4]; - uchar length[8]; - uchar blocksize[4]; - uchar md5[16]; -}; - - -struct Sac -{ - SacDir; - SacPath *path; -}; - -struct SacPath -{ - Ref; - SacPath *up; - long blocks; - int entry; - int nentry; -}; - -struct Cache -{ - long block; - ulong age; - uchar *data; -}; - -enum -{ - Pexec = 1, - Pwrite = 2, - Pread = 4, - Pother = 1, - Pgroup = 8, - Powner = 64, -}; - -static char *sacfs = "fs.sac"; -static uchar *data; -static int blocksize; -static Sac root; -static Cache cache[CacheSize]; -static ulong cacheage; - -static int sacdir(Chan *, SacDir*, uchar*, int); -static ulong getl(void *p); -static Sac *saccpy(Sac *s); -static Sac *saclookup(Sac *s, char *name); -static int sacdirread(Chan *, uchar *p, long off, long cnt); -static void loadblock(void *buf, uchar *offset, int blocksize); -static void sacfree(Sac*); - -static void -pathtoqid(ulong path, Qid *q) -{ - if(path & CHDIR) - q->type = QTDIR; - else - q->type = QTFILE; - q->path = path & ~(CHDIR|CHAPPEND|CHEXCL|CHMOUNT); - q->vers = 0; -} - -static void -omodetomode(ulong om, ulong *m) -{ - ulong nm; - - nm = om & ~(CHDIR|CHAPPEND|CHEXCL|CHMOUNT); - if(om & CHDIR) - nm |= DMDIR; - *m = nm; -} - -static void -sacinit(void) -{ - SacHeader *hdr; - uchar *p; - int i; - - p = (uchar*)Flash_tar; - data = tarlookup(p, sacfs, &i); - if(data == 0) { - p = (uchar*)Flash_tar+4; - data = tarlookup(p, sacfs, &i); - if(data == 0) { - print("devsac: could not find file: %s\n", sacfs); - return; - } - } - hdr = (SacHeader*)data; - if(getl(hdr->magic) != Magic) { - print("devsac: bad magic\n"); - return; - } - blocksize = getl(hdr->blocksize); - root.SacDir = *(SacDir*)(data + sizeof(SacHeader)); - p = malloc(CacheSize*blocksize); - if(p == nil) - error("allocating cache"); - for(i=0; iqid); - c->dev = dev; - c->aux = saccpy(&root); - return c; -} - -static void listprint(char **name, int nname, int j) -{ - int i; - - print("%d ", j); - for(i = 0; i< nname; i++) - print("%s/", name[i]); - print("\n"); -} - -static Walkqid* -sacwalk(Chan *c, Chan *nc, char **name, int nname) -{ - Sac *sac; - int j, alloc; - Walkqid *wq; - char *n; - - if(nname > 0) - isdir(c); - - alloc = 0; - wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid)); - if(waserror()){ - if(alloc && wq->clone!=nil) - cclose(wq->clone); - free(wq); - return nil; - } - if(nc == nil){ - nc = devclone(c); - nc->aux = saccpy(c->aux); - alloc = 1; - } - wq->clone = nc; - - for(j=0; jqid[wq->nqid++] = nc->qid; - continue; - } - sac = nc->aux; - sac = saclookup(sac, n); - if(sac == nil) { - if(j == 0) - error(Enonexist); - kstrcpy(up->errstr, Enonexist, ERRMAX); - break; - } - pathtoqid(getl(sac->qid), &nc->qid); - wq->qid[wq->nqid++] = nc->qid; - } - poperror(); - if(wq->nqid < nname){ -// listprint(name, wq->nqid, j); - if(alloc) - cclose(wq->clone); - wq->clone = nil; - } - return wq; -} - -static Chan* -sacopen(Chan *c, int omode) -{ - ulong t, mode; - Sac *sac; - static int access[] = { 0400, 0200, 0600, 0100 }; - - sac = c->aux; - mode = getl(sac->mode); - if(strcmp(up->user, sac->uid) == 0) - mode = mode; - else if(strcmp(up->user, sac->gid) == 0) - mode = mode<<3; - else - mode = mode<<6; - - t = access[omode&3]; - if((t & mode) != t) - error(Eperm); - c->offset = 0; - c->mode = openmode(omode); - c->flag |= COPEN; - return c; -} - - -static long -sacread(Chan *c, void *a, long n, vlong voff) -{ - Sac *sac; - char *buf, *buf2; - int nn, cnt, i, j; - uchar *blocks; - long length; - long off = voff; - - buf = a; - cnt = n; - if(c->qid.type & QTDIR) - return sacdirread(c, a, off, cnt); - sac = c->aux; - length = getl(sac->length); - if(off >= length) - return 0; - if(cnt > length-off) - cnt = length-off; - if(cnt == 0) - return 0; - n = cnt; - blocks = data + getl(sac->blocks); - buf2 = malloc(blocksize); - while(cnt > 0) { - i = off/blocksize; - nn = blocksize; - if(nn > length-i*blocksize) - nn = length-i*blocksize; - loadblock(buf2, blocks+i*OffsetSize, nn); - j = off-i*blocksize; - nn -= j; - if(nn > cnt) - nn = cnt; - memmove(buf, buf2+j, nn); - cnt -= nn; - off += nn; - buf += nn; - } - free(buf2); - return n; -} - -static long -sacwrite(Chan *, void *, long, vlong) -{ - error(Eperm); - return 0; -} - -static void -sacclose(Chan* c) -{ - Sac *sac = c->aux; - - c->aux = nil; - sacfree(sac); -} - -static int -sacstat(Chan *c, uchar *db, int n) -{ - n = sacdir(c, c->aux, db, n); - if(n == 0) - error(Ebadarg); - return n; -} - -static Sac* -saccpy(Sac *s) -{ - Sac *ss; - - ss = malloc(sizeof(Sac)); - *ss = *s; - if(ss->path) - incref(ss->path); - return ss; -} - -static SacPath * -sacpathalloc(SacPath *p, long blocks, int entry, int nentry) -{ - SacPath *pp = malloc(sizeof(SacPath)); - pp->ref = 1; - pp->blocks = blocks; - pp->entry = entry; - pp->nentry = nentry; - pp->up = p; - return pp; -} - -static void -sacpathfree(SacPath *p) -{ - if(p == nil) - return; - if(decref(p) > 0) - return; - sacpathfree(p->up); - free(p); -} - - -static void -sacfree(Sac *s) -{ - sacpathfree(s->path); - free(s); -} - -static int -sacdir(Chan *c, SacDir *s, uchar *db, int n) -{ - Dir dir; - - dir.name = s->name; - dir.uid = s->uid; - dir.gid = s->gid; - dir.muid = s->uid; - pathtoqid(getl(s->qid), &dir.qid); - omodetomode(getl(s->mode), &dir.mode); - dir.length = getl(s->length); - dir.atime = getl(s->atime); - dir.mtime = getl(s->mtime); - dir.type = devtab[c->type]->dc; - dir.dev = c->dev; - return convD2M(&dir, db, n); -} - -static void -loadblock(void *buf, uchar *offset, int blocksize) -{ - long block, n; - ulong age; - int i, j; - - block = getl(offset); - if(block < 0) { - block = -block; - cacheage++; - // age has wraped - if(cacheage == 0) { - for(i=0; ipath; - if(p == nil || p->up == nil) { - sacpathfree(p); - *s = root; - return s; - } - p = p->up; - - blocks = data + p->blocks; - per = blocksize/sizeof(SacDir); - i = p->entry/per; - n = per; - if(n > p->nentry-i*per) - n = p->nentry-i*per; - buf = malloc(per*sizeof(SacDir)); - loadblock(buf, blocks + i*OffsetSize, n*sizeof(SacDir)); - s->SacDir = buf[p->entry-i*per]; - free(buf); - incref(p); - sacpathfree(s->path); - s->path = p; - return s; -} - -/* n**2 alg to read a directory */ -static int -sacdirread(Chan *c, uchar *p, long off, long cnt) -{ - uchar *blocks; - SacDir *buf; - int per, i, j, n, ndir; - long sofar; - Sac *s; - - s = c->aux; - blocks = data + getl(s->blocks); - per = blocksize/sizeof(SacDir); - ndir = getl(s->length); - - buf = malloc(blocksize); - sofar = 0; - for(j = 0; j < ndir; j++) { - i = j%per; - if(i == 0) { - n = per; - if(n > ndir-j*per) - n = ndir-j*per; - loadblock(buf, blocks + j*OffsetSize, n*sizeof(SacDir)); - } - n = sacdir(c, buf+i, p, cnt - sofar); - if(n == 0) - break; - if(off > 0) - off -= n; - else { - p += n; - sofar += n; - } - } - free(buf); - - return sofar; -} - -static Sac* -saclookup(Sac *s, char *name) -{ - int ndir; - int i, j, k, n, per; - uchar *blocks; - SacDir *buf; - int iblock; - SacDir *sd; - - if(strcmp(name, "..") == 0) - return sacparent(s); - blocks = data + getl(s->blocks); - per = blocksize/sizeof(SacDir); - ndir = getl(s->length); - buf = malloc(per*sizeof(SacDir)); - iblock = -1; - - // linear search - for(i=0; i ndir-j*per) - n = ndir-j*per; - loadblock(buf, blocks + j*OffsetSize, n*sizeof(SacDir)); - iblock = j; - } - j *= per; - sd = buf+i-j; - k = strcmp(name, sd->name); - if(k == 0) { - s->path = sacpathalloc(s->path, getl(s->blocks), i, ndir); - s->SacDir = *sd; - free(buf); - return s; - } - } - free(buf); - return 0; -} - -static ulong -getl(void *p) -{ - uchar *a = p; - - return (a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3]; -} - -Dev sacdevtab = { - 'C', - "sac", - - devreset, - sacinit, - devshutdown, - sacattach, - sacwalk, - sacstat, - sacopen, - devcreate, - sacclose, - sacread, - devbread, - sacwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/bitsy/unsac.c b/bitsy/unsac.c deleted file mode 100644 index f918792eef7b6c1333d51bc59299900b45b14916..0000000000000000000000000000000000000000 --- a/bitsy/unsac.c +++ /dev/null @@ -1,627 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -typedef struct Huff Huff; -typedef struct Mtf Mtf; -typedef struct Decode Decode; - -enum -{ - ZBase = 2, /* base of code to encode 0 runs */ - LitBase = ZBase-1, /* base of literal values */ - MaxLit = 256, - - MaxLeaf = MaxLit+LitBase, - MaxHuffBits = 16, /* max bits in a huffman code */ - MaxFlatbits = 5, /* max bits decoded in flat table */ - - CombLog = 4, - CombSpace = 1 << CombLog, /* mtf speedup indices spacing */ - CombMask = CombSpace - 1, -}; - -struct Mtf -{ - int maxcomb; /* index of last valid comb */ - uchar prev[MaxLit]; - uchar next[MaxLit]; - uchar comb[MaxLit / CombSpace + 1]; -}; - -struct Huff -{ - int maxbits; - int flatbits; - ulong flat[1<prev[i] = last; - m->next[i] = i + 1; - last = i; - } - m->next[last] = 0; - f = 0; - - /* - * pull valid entries off free list and enter into mtf list - */ - comb = 0; - last = front[0]; - for(i = 0; i < n; i++){ - me = front[i]; - - f = m->next[me]; - m->prev[f] = m->prev[me]; - m->next[m->prev[f]] = f; - - m->next[last] = me; - m->prev[me] = last; - last = me; - if((i & CombMask) == 0) - m->comb[comb++] = me; - } - - /* - * pad out the list with dummies to the next comb, - * using free entries - */ - for(; i & CombMask; i++){ - me = f; - - f = m->next[me]; - m->prev[f] = m->prev[me]; - m->next[m->prev[f]] = f; - - m->next[last] = me; - m->prev[me] = last; - last = me; - } - me = front[0]; - m->next[last] = me; - m->prev[me] = last; - m->comb[comb] = me; - m->maxcomb = comb; -} - -static int -mtflist(Mtf *m, int pos) -{ - uchar *next, *prev, *mycomb; - int c, c0, pc, nc, off; - - if(pos == 0) - return m->comb[0]; - - next = m->next; - prev = m->prev; - mycomb = &m->comb[pos >> CombLog]; - off = pos & CombMask; - if(off >= CombSpace / 2){ - c = mycomb[1]; - for(; off < CombSpace; off++) - c = prev[c]; - }else{ - c = *mycomb; - for(; off; off--) - c = next[c]; - } - - nc = next[c]; - pc = prev[c]; - prev[nc] = pc; - next[pc] = nc; - - for(; mycomb > m->comb; mycomb--) - *mycomb = prev[*mycomb]; - c0 = *mycomb; - *mycomb = c; - mycomb[m->maxcomb] = c; - - next[c] = c0; - pc = prev[c0]; - prev[c] = pc; - prev[c0] = c; - next[pc] = c; - return c; -} - -static void -hdecblock(Decode *dec, ulong n, ulong I, uchar *buf, ulong *sums, ulong *prev) -{ - ulong i, nn, sum; - int m, z, zz, c; - - nn = I; - n--; - i = 0; -again: - for(; i < nn; i++){ - while((m = hdec(dec)) == 0 && i + dec->nzero < n) - ; - if(z = dec->nzero){ - dec->nzero = 0; - c = dec->mtf.comb[0]; - sum = sums[c]; - sums[c] = sum + z; - - z += i; - zz = z; - if(i < I && z > I){ - zz = I; - z++; - } - - zagain: - for(; i < zz; i++){ - buf[i] = c; - prev[i] = sum++; - } - if(i != z){ - zz = z; - nn = ++n; - i++; - goto zagain; - } - if(i == nn){ - if(i == n) - return; - nn = ++n; - i++; - } - } - - c = mtflist(&dec->mtf, m); - - buf[i] = c; - sum = sums[c]; - prev[i] = sum++; - sums[c] = sum; - - } - if(i == n) - return; - nn = ++n; - i++; - goto again; -} - -int -unsac(uchar *dst, uchar *src, int n, int nsrc) -{ - Decode *dec; - uchar *buf, *front; - ulong *prev, *sums; - ulong sum, i, I; - int m, j, c; - - dec = malloc(sizeof *dec); - buf = malloc(n+2); - prev = malloc((n+2) * sizeof *prev); - front = malloc(MaxLit * sizeof *front); - sums = malloc(MaxLit * sizeof *sums); - - if(waserror()){ - free(dec); - free(buf); - free(prev); - free(front); - free(sums); - nexterror(); - } - - dec->src = src; - dec->smax = src + nsrc; - - dec->nbits = 0; - dec->bits = 0; - dec->nzero = 0; - for(i = 0; i < MaxLit; i++) - front[i] = i; - - n++; - I = bitget(dec, 16); - if(I >= n) - fatal(dec, "corrupted input"); - - /* - * decode the character usage map - */ - for(i = 0; i < MaxLit; i++) - sums[i] = 0; - c = bitget(dec, 1); - for(i = 0; i < MaxLit; ){ - m = bitget(dec, 8) + 1; - while(m--){ - if(i >= MaxLit) - fatal(dec, "corrupted char map"); - front[i++] = c; - } - c = c ^ 1; - } - - /* - * initialize mtf state - */ - c = 0; - for(i = 0; i < MaxLit; i++) - if(front[i]) - front[c++] = i; - mtflistinit(&dec->mtf, front, c); - dec->maxblocksym = c + LitBase; - - /* - * huffman decoding, move to front decoding, - * along with character counting - */ - dec->base = 1; - recvtab(dec, &dec->tab, MaxLeaf, nil); - hdecblock(dec, n, I, buf, sums, prev); - - sum = 1; - for(i = 0; i < MaxLit; i++){ - c = sums[i]; - sums[i] = sum; - sum += c; - } - - i = 0; - for(j = n - 2; j >= 0; j--){ - if(i > n || i < 0 || i == I) - fatal(dec, "corrupted data"); - c = buf[i]; - dst[j] = c; - i = prev[i] + sums[c]; - } - - poperror(); - - free(dec); - free(buf); - free(prev); - free(front); - free(sums); - return n; -} - -static ulong -bitget(Decode *dec, int nb) -{ - int c; - - while(dec->nbits < nb){ - if(dec->src >= dec->smax) - fatal(dec, "premature eof 1"); - c = *dec->src++; - dec->bits <<= 8; - dec->bits |= c; - dec->nbits += 8; - } - dec->nbits -= nb; - return (dec->bits >> dec->nbits) & ((1 << nb) - 1); -} - -static void -fillbits(Decode *dec) -{ - int c; - - while(dec->nbits < 24){ - if(dec->src >= dec->smax) - fatal(dec, "premature eof 2"); - c = *dec->src++; - dec->bits <<= 8; - dec->bits |= c; - dec->nbits += 8; - } -} - -/* - * decode one symbol - */ -static int -hdecsym(Decode *dec, Huff *h, int b) -{ - long c; - ulong bits; - int nbits; - - bits = dec->bits; - nbits = dec->nbits; - for(; (c = bits >> (nbits - b)) > h->maxcode[b]; b++) - ; - if(b > h->maxbits) - fatal(dec, "too many bits consumed"); - dec->nbits = nbits - b; - return h->decode[h->last[b] - c]; -} - -static int -hdec(Decode *dec) -{ - ulong c; - int nbits, nb; - - if(dec->nbits < dec->tab.maxbits) - fillbits(dec); - nbits = dec->nbits; - dec->bits &= (1 << nbits) - 1; - c = dec->tab.flat[dec->bits >> (nbits - dec->tab.flatbits)]; - nb = c & 0xff; - c >>= 8; - if(nb == 0xff) - c = hdecsym(dec, &dec->tab, c); - else - dec->nbits = nbits - nb; - - /* - * reverse funny run-length coding - */ - if(c < ZBase){ - dec->nzero += dec->base << c; - dec->base <<= 1; - return 0; - } - - dec->base = 1; - c -= LitBase; - return c; -} - -static void -hufftab(Decode *dec, Huff *h, char *hb, ulong *bitcount, int maxleaf, int maxbits, int flatbits) -{ - ulong c, mincode, code, nc[MaxHuffBits]; - int i, b, ec; - - h->maxbits = maxbits; - if(maxbits < 0) - return; - - code = 0; - c = 0; - for(b = 0; b <= maxbits; b++){ - h->last[b] = c; - c += bitcount[b]; - mincode = code << 1; - nc[b] = mincode; - code = mincode + bitcount[b]; - if(code > (1 << b)) - fatal(dec, "corrupted huffman table"); - h->maxcode[b] = code - 1; - h->last[b] += code - 1; - } - if(code != (1 << maxbits)) - fatal(dec, "huffman table not full"); - if(flatbits > maxbits) - flatbits = maxbits; - h->flatbits = flatbits; - - b = 1 << flatbits; - for(i = 0; i < b; i++) - h->flat[i] = ~0; - - /* - * initialize the flat table to include the minimum possible - * bit length for each code prefix - */ - for(b = maxbits; b > flatbits; b--){ - code = h->maxcode[b]; - if(code == -1) - break; - mincode = code + 1 - bitcount[b]; - mincode >>= b - flatbits; - code >>= b - flatbits; - for(; mincode <= code; mincode++) - h->flat[mincode] = (b << 8) | 0xff; - } - - for(i = 0; i < maxleaf; i++){ - b = hb[i]; - if(b == -1) - continue; - c = nc[b]++; - if(b <= flatbits){ - code = (i << 8) | b; - ec = (c + 1) << (flatbits - b); - if(ec > (1<flat[c] = code; - }else{ - c = h->last[b] - c; - if(c >= maxleaf) - fatal(dec, "corrupted huffman table"); - h->decode[c] = i; - } - } -} - -static void -elimBit(int b, char *tmtf, int maxbits) -{ - int bb; - - for(bb = 0; bb < maxbits; bb++) - if(tmtf[bb] == b) - break; - while(++bb <= maxbits) - tmtf[bb - 1] = tmtf[bb]; -} - -static int -elimBits(int b, ulong *bused, char *tmtf, int maxbits) -{ - int bb, elim; - - if(b < 0) - return 0; - - elim = 0; - - /* - * increase bits counts for all descendants - */ - for(bb = b + 1; bb < maxbits; bb++){ - bused[bb] += 1 << (bb - b); - if(bused[bb] == (1 << bb)){ - elim++; - elimBit(bb, tmtf, maxbits); - } - } - - /* - * steal bits from parent & check for fullness - */ - for(; b >= 0; b--){ - bused[b]++; - if(bused[b] == (1 << b)){ - elim++; - elimBit(b, tmtf, maxbits); - } - if((bused[b] & 1) == 0) - break; - } - return elim; -} - -static void -recvtab(Decode *dec, Huff *tab, int maxleaf, ushort *map) -{ - ulong bitcount[MaxHuffBits+1], bused[MaxHuffBits+1]; - char tmtf[MaxHuffBits+1], *hb; - int i, b, ttb, m, maxbits, max, elim; - - hb = malloc(MaxLeaf * sizeof *hb); - if(waserror()) { - free(hb); - nexterror(); - } - - /* - * read the tables for the tables - */ - max = 8; - for(i = 0; i <= MaxHuffBits; i++){ - bitcount[i] = 0; - tmtf[i] = i; - bused[i] = 0; - } - tmtf[0] = -1; - tmtf[max] = 0; - elim = 0; - maxbits = -1; - for(i = 0; i <= MaxHuffBits && elim != max; i++){ - ttb = 4; - while(max - elim < (1 << (ttb-1))) - ttb--; - b = bitget(dec, ttb); - if(b > max - elim) - fatal(dec, "corrupted huffman table table"); - b = tmtf[b]; - hb[i] = b; - bitcount[b]++; - if(b > maxbits) - maxbits = b; - - elim += elimBits(b, bused, tmtf, max); - } - if(elim != max) - fatal(dec, "incomplete huffman table table"); - hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits); - for(i = 0; i <= MaxHuffBits; i++){ - tmtf[i] = i; - bitcount[i] = 0; - bused[i] = 0; - } - tmtf[0] = -1; - tmtf[MaxHuffBits] = 0; - elim = 0; - maxbits = -1; - for(i = 0; i < maxleaf && elim != MaxHuffBits; i++){ - if(dec->nbits <= tab->maxbits) - fillbits(dec); - dec->bits &= (1 << dec->nbits) - 1; - m = tab->flat[dec->bits >> (dec->nbits - tab->flatbits)]; - b = m & 0xff; - m >>= 8; - if(b == 0xff) - m = hdecsym(dec, tab, m); - else - dec->nbits -= b; - b = tmtf[m]; - for(; m > 0; m--) - tmtf[m] = tmtf[m-1]; - tmtf[0] = b; - - if(b > MaxHuffBits) - fatal(dec, "bit length too big"); - m = i; - if(map != nil) - m = map[m]; - hb[m] = b; - bitcount[b]++; - if(b > maxbits) - maxbits = b; - elim += elimBits(b, bused, tmtf, MaxHuffBits); - } - if(elim != MaxHuffBits && elim != 0) - fatal(dec, "incomplete huffman table"); - if(map != nil) - for(; i < maxleaf; i++) - hb[map[i]] = -1; - - hufftab(dec, tab, hb, bitcount, i, maxbits, MaxFlatbits); - - poperror(); - free(hb); -} - -static void -fatal(Decode *dec, char *msg) -{ - USED(dec); -print("unsac: %s\n", msg); - error(msg); -} diff --git a/pc/devarch.c b/pc/devarch.c index 7efbc53e0092a8b7b01fe7e1b02f91d3ab9a2ad1..33372acd0fed5ac1790d74a4e24fc20e0e11d105 100644 --- a/pc/devarch.c +++ b/pc/devarch.c @@ -791,6 +791,9 @@ archinit(void) if(X86FAMILY(m->cpuidax) == 3) conf.copymode = 1; +// if(X86FAMILY(m->cpuidax) >= 5 && conf.nmach > 1) + coherence = wbflush; + addarchfile("cputype", 0444, cputyperead, nil); addarchfile("pge", 0664, pgeread, pgewrite); } diff --git a/pc/fns.h b/pc/fns.h index 3e1d42a6170a12e9d4e94531346111ff771d99d9..498b7b7e582cb7150a437fa9acb105fb91efe314 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -10,7 +10,6 @@ int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); #define clearmmucache() /* x86 doesn't have one */ void clockintr(Ureg*, void*); -void clockintrsched(void); void (*coherence)(void); void cpuid(char*, int*, int*); int cpuidentify(void); @@ -126,6 +125,7 @@ void rdtsc(vlong*); void screeninit(void); int screenprint(char*, ...); /* debugging */ void (*screenputs)(char*, int); +void sfence(void); void touser(void*); void trapenable(int, void (*)(Ureg*, void*), void*, char*); void trapinit(void); @@ -140,6 +140,7 @@ void upafree(ulong, int); void vectortable(void); void wrmsr(int, vlong); void wbflush(void); +void wbinvd(void); int xchgw(ushort*, int); ulong TK2MS(ulong); /* ticks to milliseconds */ diff --git a/pc/l.s b/pc/l.s index 4241162c147ca58959dae6886e78d61c07b8541f..a472dee93594d9fe4a163a7cf4d1531febbd2575 100644 --- a/pc/l.s +++ b/pc/l.s @@ -14,6 +14,7 @@ #define RDTSC BYTE $0x0F; BYTE $0x31 #define WBINVD BYTE $0x0F; BYTE $0x09 #define HLT BYTE $0xF4 +#define SFENCE BYTE $0x0F; BYTE $0xAE; BYTE $0xF8 /* * Macros for calculating offsets within the page directory base @@ -303,6 +304,10 @@ TEXT wbinvd(SB), $0 WBINVD RET +TEXT sfence(SB), $0 + SFENCE + RET + /* * Try to determine the CPU type which requires fiddling with EFLAGS. * If the Id bit can be toggled then the CPUID instruciton can be used @@ -498,6 +503,16 @@ TEXT gotolabel(SB), $0 MOVL $1, AX /* return 1 */ RET +TEXT swaplabel(SB), $0 + MOVL label+0(FP), AX + MOVL pc+4(FP), BX + MOVL 0(AX), SP /* restore sp */ + MOVL 4(AX), CX /* put return pc on the stack */ + MOVL CX, 0(SP) + MOVL BX, 4(AX) /* put caller pc where return pc was */ + MOVL $1, AX /* return 1 */ + RET + TEXT setlabel(SB), $0 MOVL label+0(FP), AX MOVL SP, 0(AX) /* store sp */ diff --git a/port/devloopback.c b/port/devloopback.c index 8322e9b6ea399194eb78e09fe12e701dc4ba3fdf..9b4aa23f93405079390d7270d61e6073b5ac77b5 100644 --- a/port/devloopback.c +++ b/port/devloopback.c @@ -597,7 +597,6 @@ looper(Loop *lb) t = fastticks(nil); for(chan = 0; chan < 2; chan++) pushlink(&lb->link[chan], t); - clockintrsched(); } static void diff --git a/port/devtls.c b/port/devtls.c index 90bd7eacc9dbcd67efd02e915d7bbde6b5255f33..197fb3c13c5ec6293c5807e39e697df4257d4bab 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -760,8 +760,8 @@ tlsrecread(TlsRec *tr) len = get16(header+3); } if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion)) - rcvError(tr, EProtocolVersion, "record layer saw ver %x, not %x/%d; %d %d", - ver, tr->version, tr->verset, type, len); + rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'", + tr->version, tr->verset?"/set":"", len, type, ver, (char*)header); if(len > MaxCipherRecLen || len < 0) rcvError(tr, ERecordOverflow, "record message too long %d", len); ensure(tr, &tr->unprocessed, len); diff --git a/port/nulledf.c b/port/nulledf.c index ef821c268bd5786fa60909281cf4b2acfe9f7cb7..7ab36fc3152edbe2a5c3d1812f5934b3578b84ed 100644 --- a/port/nulledf.c +++ b/port/nulledf.c @@ -13,29 +13,29 @@ isedf(Proc*) } void -edf_bury(Proc*) +edfbury(Proc*) { } int -edf_anyready(void) +edfanyready(void) { return 0; } void -edf_ready(Proc*) +edfready(Proc*) { } Proc* -edf_runproc(void) +edfrunproc(void) { return nil; } void -edf_block(Proc*) +edfblock(Proc*) { } diff --git a/port/portclock.c b/port/portclock.c index fcdde883ccacf2700ed41e0f341cbbf663ee62c7..ad1319c76a6a9f72ab9e7d3958482dc1a5929889 100644 --- a/port/portclock.c +++ b/port/portclock.c @@ -96,10 +96,6 @@ hzclock(Ureg *ur) if(m->proc) m->proc->pc = ur->pc; - if(m->inclockintr) - return; /* interrupted ourself */ - m->inclockintr = 1; - if(m->flushmmu){ if(up) flushmmu(); @@ -148,10 +144,14 @@ timerintr(Ureg *u, uvlong) uvlong when, now; int callhzclock; + if(m->inclockintr) + return; + m->inclockintr = 1; + intrcount[m->machno]++; callhzclock = 0; tt = &timers[m->machno]; - now = (uvlong)fastticks(nil); + now = fastticks(nil); ilock(tt); while(t = tt->head){ when = t->when; @@ -160,6 +160,7 @@ timerintr(Ureg *u, uvlong) timerset(when); if(callhzclock) hzclock(u); + m->inclockintr = 0; return; } tt->head = t->next; @@ -179,6 +180,7 @@ timerintr(Ureg *u, uvlong) } } iunlock(tt); + m->inclockintr = 0; } uvlong hzperiod; @@ -190,7 +192,8 @@ timersinit(void) hzperiod = ms2fastticks(1000/HZ); - t = smalloc(sizeof(*t)); + t = malloc(sizeof(*t)); + t->when = 0; t->period = hzperiod; t->f = nil; timeradd(t); @@ -216,8 +219,3 @@ addclock0link(void (*f)(void)) */ iunlock(&timers[0]); } - -void -clockintrsched(void) -{ -} diff --git a/port/proc.c b/port/proc.c index 04eaa83907ae50010cf836a62f9121cc5e9d8a98..6a1e04ae810eefa6b618d5c16b7162c6c1d30b89 100644 --- a/port/proc.c +++ b/port/proc.c @@ -1146,6 +1146,7 @@ error(char *err) { spllo(); kstrcpy(up->errstr, err, ERRMAX); + setlabel(&up->errlab[NERR-1]); nexterror(); } diff --git a/port/taslock.c b/port/taslock.c index 90262941514829af57150229bd5565dfdba03895..e0e6e66c01f1a62ec8b801a0ab2631df92832e9d 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -152,6 +152,7 @@ canlock(Lock *l) return 1; } +int buggeredsched; void unlock(Lock *l) { @@ -165,11 +166,15 @@ unlock(Lock *l) coherence(); /* give up the processor if ... */ - if(up && --up->nlocks == 0 /* we've closed the last nexted lock */ + if(up && --up->nlocks == 0 /* we've closed the last nested lock */ && up->delaysched /* we delayed scheduling because of the lock */ - && up->state == Running){ /* we're in running state */ - up->delaysched = 0; - sched(); + && up->state == Running){ /* we're in running state */ + if(!islo()) + buggeredsched++; + else{ + up->delaysched = 0; + sched(); + } } }