## diffname power/lock.c 1990/0227 ## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/lock.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" /* * The hardware semaphores are strange. 64 per page, replicated 16 times * per page, 1024 pages of them. Only the low bit is meaningful. * Reading an unset semaphore sets the semaphore and returns the old value. * Writing a semaphore sets the value, so writing 0 resets (clears) the semaphore. */ #define SEMPERPG 64 /* hardware semaphores per page */ #define NONSEMPERPG (WD2PG-64) /* words of non-semaphore per page */ struct { Lock lock; /* lock to allocate */ ulong *nextsem; /* next one to allocate */ int nsem; /* at SEMPERPG, jump to next page */ }semalloc; void lockinit(void) { semalloc.lock.sbsem = SBSEM; semalloc.nextsem = SBSEM+1; semalloc.nsem = 1; unlock(&semalloc.lock); } /* * If l->sbsem is zero, allocate a hardware semaphore first. * There is no way to free a semaphore. */ void lock(Lock *l) { int addr; int i; ulong *sbsem; sbsem = l->sbsem; if(sbsem == 0){ lock(&semalloc.lock); if(semalloc.nsem == SEMPERPG){ semalloc.nsem = 0; semalloc.nextsem += NONSEMPERPG; if(semalloc.nextsem == SBSEMTOP) panic("sem"); } l->sbsem = semalloc.nextsem; semalloc.nextsem++; semalloc.nsem++; unlock(&semalloc.lock); unlock(l); /* put sem in known state */ sbsem = l->sbsem; } /* * Try the fast grab first */ if((*sbsem&1) == 0){ l->pc = ((ulong*)&addr)[-7]; return; } for(i=0; i<10000000; i++) if((*sbsem&1) == 0){ l->pc = ((ulong*)&addr)[-7]; return; } *sbsem = 0; print("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&addr)[-7], l->pc); } int canlock(Lock *l) { ulong *sbsem; sbsem = l->sbsem; if(sbsem == 0){ lock(&semalloc.lock); if(semalloc.nsem == SEMPERPG){ semalloc.nsem = 0; semalloc.nextsem += NONSEMPERPG; if(semalloc.nextsem == SBSEMTOP) panic("sem"); } l->sbsem = semalloc.nextsem; semalloc.nextsem++; semalloc.nsem++; unlock(&semalloc.lock); unlock(l); /* put sem in known state */ sbsem = l->sbsem; } if(*sbsem & 1) return 0; return 1; } void unlock(Lock *l) { l->pc = 0; *l->sbsem = 0; } int canqlock(QLock *q) { return canlock(&q->use); } void qlock(QLock *q) { Proc *p; if(canlock(&q->use)) return; lock(&q->queue); if(canlock(&q->use)){ unlock(&q->queue); return; } p = q->tail; if(p == 0) q->head = u->p; else p->qnext = u->p; q->tail = u->p; u->p->qnext = 0; u->p->state = Queueing; unlock(&q->queue); sched(); } void qunlock(QLock *q) { Proc *p; lock(&q->queue); if(q->head){ p = q->head; q->head = p->qnext; if(q->head == 0) q->tail = 0; unlock(&q->queue); ready(p); }else{ unlock(&q->use); unlock(&q->queue); } } . ## diffname power/lock.c 1990/0322 ## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/lock.c /n/bootesdump/1990/0322/sys/src/9/mips/lock.c 154,155c q->locked = 0; unlock(q); . 151c unlock(q); . 145,147c lock(q); p = q->head; if(p){ . 136c unlock(q); . 123,126d 121c lock(q); if(!q->locked){ q->locked = 1; unlock(q); . 113c lock(q); if(q->locked){ unlock(q); return 0; } q->locked = 1; unlock(q); return 1; . ## diffname power/lock.c 1990/0324 ## diff -e /n/bootesdump/1990/0322/sys/src/9/mips/lock.c /n/bootesdump/1990/0324/sys/src/9/mips/lock.c 160,161c unlock(&q->use); unlock(&q->queue); . 157c unlock(&q->queue); . 151,153c lock(&q->queue); if(q->head){ p = q->head; . 142c unlock(&q->queue); . 132a lock(&q->queue); if(canlock(&q->use)){ unlock(&q->queue); return; . 128,131c if(canlock(&q->use)) . 113,120c return canlock(&q->use); . ## diffname power/lock.c 1990/1115 ## diff -e /n/bootesdump/1990/0324/sys/src/9/mips/lock.c /n/bootesdump/1990/1115/sys/src/9/mips/lock.c 74a dumpstack(); . ## diffname power/lock.c 1990/1214 ## diff -e /n/bootesdump/1990/1115/sys/src/9/mips/lock.c /n/bootesdump/1990/1214/sys/src/9/mips/lock.c 74c print("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&ll)[PCOFF], l->pc); . 70c l->pc = ((ulong*)&ll)[PCOFF]; . 64,65c if((*sbsem&1) == 0){ l->pc = ((ulong*)&ll)[PCOFF]; . 41c Lock *l = ll; . 39c lock(Lock *ll) . 33a #define PCOFF -9 . ## diffname power/lock.c 1991/0428 ## diff -e /n/bootesdump/1991/0201/sys/src/9/mips/lock.c /n/bootesdump/1991/0428/sys/src/9/power/lock.c 112,160d ## diffname power/lock.c 1991/0605 ## diff -e /n/bootesdump/1991/0428/sys/src/9/power/lock.c /n/bootesdump/1991/0605/sys/src/9/power/lock.c 90,92c semalloc.nextsem = lkpgalloc(); . 77c dumpstack(); . 52,54c semalloc.nextsem = lkpgalloc(); . 38d 33a /* return the address of the next free page of locks */ ulong* lkpgalloc(void) { uchar *p, *top; top = &semalloc.bmap[NSEMPG]; for(p = semalloc.bmap; *p && p < top; p++) ; if(p == top) panic("lkpgalloc"); *p = 1; return (p-semalloc.bmap)*WD2PG + SBSEM; } void lkpgfree(ulong *lpa) { uchar *p; p = &semalloc.bmap[(lpa-SBSEM)/WD2PG]; if(!*p) panic("lkpgfree"); *p = 0; } . 27a memset(semalloc.bmap, 0, sizeof(semalloc.bmap)); semalloc.bmap[0] = 1; . 22a uchar bmap[NSEMPG]; /* allocation map */ . 16c #define NSEMPG 1024 . ## diffname power/lock.c 1991/0606 ## diff -e /n/bootesdump/1991/0605/sys/src/9/power/lock.c /n/bootesdump/1991/0606/sys/src/9/power/lock.c 135a } void mklockseg(Seg *s) { Orig *o; s->proc = u->p; o = neworig(LKSEGBASE, 0, OWRPERM|OPURE, 0); o->minca = 0; o->maxca = 0; s->o = o; s->minva = LKSEGBASE; s->maxva = LKSEGBASE; s->mod = 0; . 52a /* Moral equivalent of newpage for pages of hardware lock */ Page* lkpage(Orig *o, ulong va) { uchar *p, *top; Page *pg; int i; lock(&semalloc.lock); top = &semalloc.bmap[NSEMPG]; for(p = semalloc.bmap; *p && p < top; p++) ; if(p == top) panic("lkpage"); *p = 1; i = p-semalloc.bmap; pg = &lkpgheader[i]; pg->pa = (ulong)((i*WD2PG) + SBSEM); pg->va = va; pg->o = o; unlock(&semalloc.lock); return pg; } . 30a . 25a Page lkpgheader[NSEMPG]; . 6a #include "errno.h" . ## diffname power/lock.c 1991/0607 ## diff -e /n/bootesdump/1991/0606/sys/src/9/power/lock.c /n/bootesdump/1991/0607/sys/src/9/power/lock.c 176a o->freepg = lkpgfree; . 174c o = neworig(LKSEGBASE, 0, OWRPERM|OSHARED, 0); . 91a semalloc.ulockpg++; unlock(&semalloc.lock); . 88c lock(&semalloc.lock); p = &semalloc.bmap[((pg->pa|UNCACHED)-(ulong)SBSEM)/BY2PG]; . 84c lkpgfree(Page *pg, int dolock) . 77a pg->ref = 1; . 75c pg->pa = (ulong)((i*WD2PG) + SBSEM) & ~UNCACHED; . 65a if(--semalloc.ulockpg < 0) { semalloc.ulockpg++; unlock(&semalloc.lock); return 0; } . 34a semalloc.ulockpg = ULOCKPG; . 24a int ulockpg; /* count of user lock available */ . 17a #define ULOCKPG 512 . ## diffname power/lock.c 1991/0614 ## diff -e /n/bootesdump/1991/0607/sys/src/9/power/lock.c /n/bootesdump/1991/0614/sys/src/9/power/lock.c 178a if(u && u->p) u->p->hasspin = 0; . 170a if(u && u->p) u->p->hasspin = 1; . 142a if(u && u->p) u->p->hasspin = 1; . 137a if(u && u->p) u->p->hasspin = 1; . ## diffname power/lock.c 1991/0705 ## diff -e /n/bootesdump/1991/0614/sys/src/9/power/lock.c /n/bootesdump/1991/0705/sys/src/9/power/lock.c 185,202d 175,176d 145,146d 138,139d 93c lkpgfree(Page *pg) . 85d 62c lkpage(ulong va) . ## diffname power/lock.c 1991/0726 ## diff -e /n/bootesdump/1991/0705/sys/src/9/power/lock.c /n/bootesdump/1991/0726/sys/src/9/power/lock.c 169a l->pc = getcallerpc(); . 145c print("lock loop %lux pc %lux held by pc %lux\n", l, getcallerpc(), l->pc); . 141c l->pc = getcallerpc(); . 136c l->pc = getcallerpc(); . 114d 112c lock(Lock *l) . 106,107d ## diffname power/lock.c 1991/0802 ## diff -e /n/bootesdump/1991/0726/sys/src/9/power/lock.c /n/bootesdump/1991/0802/sys/src/9/power/lock.c 162d 158,160d 154,156c if(l->sbsem == 0){ if(semalloc.nsem == SEMPERPG){ semalloc.nsem = 0; semalloc.nextsem = lkpgalloc(); } l->sbsem = semalloc.nextsem; semalloc.nextsem++; semalloc.nsem++; unlock(l); /* put sem in known state */ . 126d 122,124d 118,120c if(l->sbsem == 0){ if(semalloc.nsem == SEMPERPG){ semalloc.nsem = 0; semalloc.nextsem = lkpgalloc(); } l->sbsem = semalloc.nextsem; semalloc.nextsem++; semalloc.nsem++; unlock(l); /* put sem in known state */ . ## diffname power/lock.c 1992/0111 ## diff -e /n/bootesdump/1991/0802/sys/src/9/power/lock.c /n/bootesdump/1992/0111/sys/src/9/power/lock.c 7c #include "../port/error.h" . ## diffname power/lock.c 1992/0222 ## diff -e /n/bootesdump/1992/0111/sys/src/9/power/lock.c /n/bootesdump/1992/0222/sys/src/9/power/lock.c 171c l->pc = getcallerpc(l); . 144c print("lock loop %lux pc %lux held by pc %lux\n", l, getcallerpc(l), l->pc); . 140c l->pc = getcallerpc(l); . 135c l->pc = getcallerpc(l); . ## diffname power/lock.c 1992/0321 ## diff -e /n/bootesdump/1992/0222/sys/src/9/power/lock.c /n/bootesdump/1992/0321/sys/src/9/power/lock.c 2c #include "../port/lib.h" . ## diffname power/lock.c 1992/0622 ## diff -e /n/bootesdump/1992/0321/sys/src/9/power/lock.c /n/bootesdump/1992/0622/sys/src/9/power/lock.c 179c l->val = 0; . 169,172d 166,167c if(lk->val) return 0; . 161,164d 153,159c hash = lhash(lk); hwsem = (int*)SBSEM+hash; for(;;) { if((*hwsem & 1) == 0) { if(lk->val) *hwsem = 0; else { lk->val = 1; *hwsem = 0; lk->pc = getcallerpc(lk); return 1; . 151c int *hwsem; int i, hash; . 149c canlock(Lock *lk) . 146c } . 131,144c print("lock loop %lux pc %lux held by pc %lux\n", lk, getcallerpc(lk), lk->pc); . 128,129c while(lk->val && i) i--; if(i <= 0) break; . 123,126d 115,121c hash = lhash(lk); hwsem = (int*)SBSEM+hash; i = 1000000; for(;;) { if((*hwsem & 1) == 0) { if(lk->val) *hwsem = 0; else { lk->val = 1; *hwsem = 0; lk->pc = getcallerpc(lk); return; . 112,113c int *hwsem; int i, hash; . 110c lock(Lock *lk) . 106,108d 44,60c /* Moral equivalent of newpage for pages of hardware locks */ . 38,41d 35,36c /* * Initialise the system semaphore hardware */ memset(SBSEM, 0, (NSEMPG-ULOCKPG)*BY2PG); . 29a #define lhash(laddr) ((int)laddr>>2)&(((NSEMPG-ULOCKPG)*(BY2PG>>2))-1) . 23,24d 16,18c enum { SEMPERPG = 64, /* hardware semaphores per page */ NSEMPG = 1024, ULOCKPG = 512, }; . ## diffname power/lock.c 1992/0629 ## diff -e /n/bootesdump/1992/0622/sys/src/9/power/lock.c /n/bootesdump/1992/0629/sys/src/9/power/lock.c 127,142c return muxlock((int*)SBSEM+hash, &lk->val); . 123,124c int hash; . 101,114c if(muxlock(hwsem, &lk->val)) return; while(lk->val) ; . 99d 93,94c int *hwsem, hash; . 61c if(p >= top) . 59c for(p = semalloc.bmap; p < top && *p; p++) . 44c /* equivalent of newpage for pages of hardware locks */ . 40c for(i = 0; i < (NSEMPG-ULOCKPG)*BY2PG; i += 4) { h = lhash(i); sbsem = (int*)SBSEM+h; *sbsem = 0; } . 36c int *sbsem, h, i; . 31c #define lhash(laddr) ((int)laddr>>2)&(((NSEMPG-ULOCKPG)*(BY2PG>>2))-1)&~0x3c0 . 10,11c * The hardware semaphores are strange. Only 64 per page can be used, * 1024 pages of them. Only the low bit is meaningful. . ## diffname power/lock.c 1993/0120 ## diff -e /n/bootesdump/1992/0629/sys/src/9/power/lock.c /n/bootesdump/1993/0120/sys/src/9/power/lock.c 56a USED(s); . 51c lkpage(Segment *s, ulong va) . ## diffname power/lock.c 1993/0501 ## diff -e /n/bootesdump/1993/0120/sys/src/9/power/lock.c /n/fornaxdump/1993/0501/sys/src/brazil/power/lock.c 55a Page *pg; uchar *p, *top; . 53,54d ## diffname power/lock.c 1994/0218 ## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/power/lock.c /n/fornaxdump/1994/0218/sys/src/brazil/power/lock.c 73c pa = (ulong)(SBSEM+(i*WD2PG)); memset((void*)pa, 0, BY2PG); pg->pa = pa & ~UNCACHED; . 55a ulong pa; . ## diffname power/lock.c 1994/0405 ## diff -e /n/fornaxdump/1994/0218/sys/src/brazil/power/lock.c /n/fornaxdump/1994/0405/sys/src/brazil/power/lock.c 130a } void iunlock(Lock *l) { ulong sr; sr = l->sr; l->pc = 0; l->val = 0; splx(sr); . 116a void ilock(Lock *lk) { int *hwsem, hash; ulong x; x = splhi(); hash = lhash(lk); hwsem = (int*)SBSEM+hash; for(;;) { if(muxlock(hwsem, &lk->val)){ lk->sr = x; return; } while(lk->val) ; } splx(x); print("lock loop %lux pc %lux held by pc %lux\n", lk, getcallerpc(lk), lk->pc); dumpstack(); } . ## diffname power/lock.c 1997/0327 # deleted ## diff -e /n/fornaxdump/1994/0405/sys/src/brazil/power/lock.c /n/emeliedump/1997/0327/sys/src/brazil/power/lock.c 1,165d