## 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
|