reverting semaphore lock changes from sources (r41ccd6d221da, rb28756e5ba29)
semaphore locks have much higher overhead than initially presented in the "Semaphores in Plan9" paper. until the reason for it has been found out i will revert the changes.
This commit is contained in:
parent
b4cdfc6c55
commit
cdc2c30e99
39 changed files with 521 additions and 611 deletions
|
@ -24,6 +24,7 @@ SFILES=\
|
|||
strlen.s\
|
||||
|
||||
CFILES=\
|
||||
cycles.c\
|
||||
notejmp.c\
|
||||
vlrt.c\
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
lock(Lock *lk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* once fast */
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
/* a thousand times pretty fast */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(0);
|
||||
}
|
||||
/* now nice and slow */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(100);
|
||||
}
|
||||
/* take your time */
|
||||
while(_tas((int*)&lk->key))
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
if(_tas((int*)&lk->key))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
lk->key = 0;
|
||||
}
|
|
@ -26,7 +26,7 @@ SFILES=\
|
|||
vlop.s\
|
||||
|
||||
CFILES=\
|
||||
lock.c\
|
||||
cycles.c\
|
||||
notejmp.c\
|
||||
vlrt.c\
|
||||
|
||||
|
|
7
sys/src/libc/alpha/cycles.c
Normal file
7
sys/src/libc/alpha/cycles.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void cycles(uvlong*u)
|
||||
{
|
||||
*u = 0LL;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
lock(Lock *lk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* once fast */
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
/* a thousand times pretty fast */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(0);
|
||||
}
|
||||
/* now nice and slow */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(100);
|
||||
}
|
||||
/* take your time */
|
||||
while(_tas((int*)&lk->key))
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
if(_tas((int*)&lk->key))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
lk->key = 0;
|
||||
}
|
|
@ -18,7 +18,7 @@ SFILES=\
|
|||
|
||||
CFILES=\
|
||||
_seek.c\
|
||||
lock.c\
|
||||
cycles.c\
|
||||
notejmp.c\
|
||||
|
||||
HFILES=/sys/include/libc.h
|
||||
|
|
10
sys/src/libc/arm/cycles.c
Normal file
10
sys/src/libc/arm/cycles.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
#pragma profile off
|
||||
|
||||
void
|
||||
cycles(uvlong*u)
|
||||
{
|
||||
*u = 0LL;
|
||||
}
|
|
@ -20,6 +20,7 @@ SFILES=\
|
|||
vlop.s\
|
||||
|
||||
CFILES=\
|
||||
cycles.c\
|
||||
notejmp.c\
|
||||
vlrt.c\
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@ TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */
|
|||
loop: MOVW $1, R3
|
||||
LL(2, 1)
|
||||
NOOP
|
||||
ADDU R1, R3
|
||||
MOVW R3, R1 /* return new value */
|
||||
ADD R1,R3,R3
|
||||
SC(2, 3)
|
||||
NOOP
|
||||
BEQ R3,loop
|
||||
|
@ -25,8 +24,8 @@ TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */
|
|||
loop1: MOVW $-1, R3
|
||||
LL(2, 1)
|
||||
NOOP
|
||||
ADDU R1, R3
|
||||
MOVW R3, R1 /* return new value */
|
||||
ADD R1,R3,R3
|
||||
MOVW R3, R1
|
||||
SC(2, 3)
|
||||
NOOP
|
||||
BEQ R3,loop1
|
||||
|
@ -50,3 +49,9 @@ spincas:
|
|||
fail:
|
||||
MOVW $0, R1
|
||||
RET
|
||||
|
||||
/* general-purpose abort */
|
||||
_trap:
|
||||
MOVD $0, R0
|
||||
MOVD 0(R0), R0
|
||||
RET
|
||||
|
|
171
sys/src/libc/mips/lock.c
Normal file
171
sys/src/libc/mips/lock.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
enum
|
||||
{
|
||||
Pagesize = 4096,
|
||||
Semperpg = Pagesize/(16*sizeof(uint)),
|
||||
Lockaddr = 0x60000000,
|
||||
|
||||
POWER = 0x320,
|
||||
MAGNUM = 0x330,
|
||||
MAGNUMII = 0x340,
|
||||
R4K = 0x500,
|
||||
};
|
||||
|
||||
static int arch;
|
||||
extern int C_3ktas(int*);
|
||||
extern int C_4ktas(int*);
|
||||
extern int C_fcr0(void);
|
||||
|
||||
static void
|
||||
lockinit(void)
|
||||
{
|
||||
void *v;
|
||||
|
||||
if(arch != 0)
|
||||
return; /* allow multiple calls */
|
||||
arch = C_fcr0();
|
||||
switch(arch) {
|
||||
case POWER:
|
||||
v = (void*)Lockaddr;
|
||||
if(segattach(SG_CEXEC, "lock", v, Pagesize) == (void*)-1) {
|
||||
arch = MAGNUM;
|
||||
break;
|
||||
}
|
||||
memset(v, 0, Pagesize);
|
||||
break;
|
||||
case MAGNUM:
|
||||
case MAGNUMII:
|
||||
case R4K:
|
||||
break;
|
||||
default:
|
||||
arch = R4K;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lock(Lock *lk)
|
||||
{
|
||||
int *hwsem;
|
||||
int hash;
|
||||
|
||||
retry:
|
||||
switch(arch) {
|
||||
case 0:
|
||||
lockinit();
|
||||
goto retry;
|
||||
case MAGNUM:
|
||||
case MAGNUMII:
|
||||
while(C_3ktas(&lk->val))
|
||||
sleep(0);
|
||||
return;
|
||||
case R4K:
|
||||
for(;;){
|
||||
while(lk->val)
|
||||
;
|
||||
if(C_4ktas(&lk->val) == 0)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case POWER:
|
||||
/* Use low order lock bits to generate hash */
|
||||
hash = ((int)lk/sizeof(int)) & (Semperpg-1);
|
||||
hwsem = (int*)Lockaddr+hash;
|
||||
|
||||
for(;;) {
|
||||
if((*hwsem & 1) == 0) {
|
||||
if(lk->val)
|
||||
*hwsem = 0;
|
||||
else {
|
||||
lk->val = 1;
|
||||
*hwsem = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while(lk->val)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
int *hwsem;
|
||||
int hash;
|
||||
|
||||
retry:
|
||||
switch(arch) {
|
||||
case 0:
|
||||
lockinit();
|
||||
goto retry;
|
||||
case MAGNUM:
|
||||
case MAGNUMII:
|
||||
if(C_3ktas(&lk->val))
|
||||
return 0;
|
||||
return 1;
|
||||
case R4K:
|
||||
if(C_4ktas(&lk->val))
|
||||
return 0;
|
||||
return 1;
|
||||
case POWER:
|
||||
/* Use low order lock bits to generate hash */
|
||||
hash = ((int)lk/sizeof(int)) & (Semperpg-1);
|
||||
hwsem = (int*)Lockaddr+hash;
|
||||
|
||||
if((*hwsem & 1) == 0) {
|
||||
if(lk->val)
|
||||
*hwsem = 0;
|
||||
else {
|
||||
lk->val = 1;
|
||||
*hwsem = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
lk->val = 0;
|
||||
}
|
||||
|
||||
int
|
||||
_tas(int *p)
|
||||
{
|
||||
int *hwsem;
|
||||
int hash;
|
||||
|
||||
retry:
|
||||
switch(arch) {
|
||||
case 0:
|
||||
lockinit();
|
||||
goto retry;
|
||||
case MAGNUM:
|
||||
case MAGNUMII:
|
||||
return C_3ktas(p);
|
||||
case R4K:
|
||||
return C_4ktas(p);
|
||||
case POWER:
|
||||
/* Use low order lock bits to generate hash */
|
||||
hash = ((int)p/sizeof(int)) & (Semperpg-1);
|
||||
hwsem = (int*)Lockaddr+hash;
|
||||
|
||||
if((*hwsem & 1) == 0) {
|
||||
if(*p)
|
||||
*hwsem = 0;
|
||||
else {
|
||||
*p = 1;
|
||||
*hwsem = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -23,6 +23,7 @@ SFILES=\
|
|||
|
||||
CFILES=\
|
||||
cycles.c\
|
||||
lock.c\
|
||||
notejmp.c\
|
||||
sqrt.c\
|
||||
vlrt.c\
|
||||
|
|
|
@ -17,7 +17,6 @@ btas:
|
|||
BLTZ R1, btas
|
||||
RET
|
||||
|
||||
TEXT _tas(SB),$0
|
||||
TEXT C_4ktas(SB), $0
|
||||
MOVW R1, R2 /* address of key */
|
||||
tas1:
|
||||
|
|
|
@ -37,7 +37,7 @@ update:V:
|
|||
cd $i
|
||||
mk $MKFLAGS update
|
||||
}
|
||||
update $UPDATEFLAGS /$objtype/lib/libc.a
|
||||
update $UPDATEFLAGS /386/lib/libc.a
|
||||
|
||||
installall:V:
|
||||
for(objtype in $CPUS) mk $MKFLAGS install
|
||||
|
|
|
@ -2,32 +2,40 @@
|
|||
#include <libc.h>
|
||||
|
||||
void
|
||||
lock(Lock *l)
|
||||
lock(Lock *lk)
|
||||
{
|
||||
if(ainc(&l->key) == 1)
|
||||
return; /* changed from 0 -> 1: we hold lock */
|
||||
/* otherwise wait in kernel */
|
||||
while(semacquire(&l->sem, 1) < 0){
|
||||
/* interrupted; try again */
|
||||
}
|
||||
}
|
||||
int i;
|
||||
|
||||
void
|
||||
unlock(Lock *l)
|
||||
{
|
||||
if(adec(&l->key) == 0)
|
||||
return; /* changed from 1 -> 0: no contention */
|
||||
semrelease(&l->sem, 1);
|
||||
/* once fast */
|
||||
if(!_tas(&lk->val))
|
||||
return;
|
||||
/* a thousand times pretty fast */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas(&lk->val))
|
||||
return;
|
||||
sleep(0);
|
||||
}
|
||||
/* now nice and slow */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas(&lk->val))
|
||||
return;
|
||||
sleep(100);
|
||||
}
|
||||
/* take your time */
|
||||
while(_tas(&lk->val))
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *l)
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
if(ainc(&l->key) == 1)
|
||||
return 1; /* changed from 0 -> 1: success */
|
||||
/* Undo increment (but don't miss wakeup) */
|
||||
if(adec(&l->key) == 0)
|
||||
return 0; /* changed from 1 -> 0: no contention */
|
||||
semrelease(&l->sem, 1);
|
||||
return 0;
|
||||
if(_tas(&lk->val))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
lk->val = 0;
|
||||
}
|
||||
|
|
|
@ -122,18 +122,16 @@ Profuser = 1;
|
|||
Profkernel = 2;
|
||||
Proftime = 3;
|
||||
Profsample = 4;
|
||||
sizeofLock = 8;
|
||||
sizeofLock = 4;
|
||||
aggr Lock
|
||||
{
|
||||
'D' 0 key;
|
||||
'D' 4 sem;
|
||||
'D' 0 val;
|
||||
};
|
||||
|
||||
defn
|
||||
Lock(addr) {
|
||||
complex Lock addr;
|
||||
print(" key ", addr.key, "\n");
|
||||
print(" sem ", addr.sem, "\n");
|
||||
print(" val ", addr.val, "\n");
|
||||
};
|
||||
|
||||
sizeofQLp = 12;
|
||||
|
@ -152,13 +150,13 @@ QLp(addr) {
|
|||
print(" state ", addr.state, "\n");
|
||||
};
|
||||
|
||||
sizeofQLock = 20;
|
||||
sizeofQLock = 16;
|
||||
aggr QLock
|
||||
{
|
||||
Lock 0 lock;
|
||||
'D' 8 locked;
|
||||
'A' QLp 12 $head;
|
||||
'A' QLp 16 $tail;
|
||||
'D' 4 locked;
|
||||
'A' QLp 8 $head;
|
||||
'A' QLp 12 $tail;
|
||||
};
|
||||
|
||||
defn
|
||||
|
@ -172,14 +170,14 @@ QLock(addr) {
|
|||
print(" $tail ", addr.$tail\X, "\n");
|
||||
};
|
||||
|
||||
sizeofRWLock = 24;
|
||||
sizeofRWLock = 20;
|
||||
aggr RWLock
|
||||
{
|
||||
Lock 0 lock;
|
||||
'D' 8 readers;
|
||||
'D' 12 writer;
|
||||
'A' QLp 16 $head;
|
||||
'A' QLp 20 $tail;
|
||||
'D' 4 readers;
|
||||
'D' 8 writer;
|
||||
'A' QLp 12 $head;
|
||||
'A' QLp 16 $tail;
|
||||
};
|
||||
|
||||
defn
|
||||
|
@ -440,12 +438,12 @@ Tos(addr) {
|
|||
};
|
||||
|
||||
complex Tos _tos;
|
||||
sizeofPrivate = 16;
|
||||
sizeofPrivate = 12;
|
||||
aggr Private
|
||||
{
|
||||
Lock 0 lk;
|
||||
'D' 8 pid;
|
||||
'D' 12 printfd;
|
||||
'D' 4 pid;
|
||||
'D' 8 printfd;
|
||||
};
|
||||
|
||||
defn
|
||||
|
|
|
@ -19,7 +19,6 @@ CFILES=\
|
|||
cleanname.c\
|
||||
crypt.c\
|
||||
ctype.c\
|
||||
cycles.c\
|
||||
encodefmt.c\
|
||||
execl.c\
|
||||
exp.c\
|
||||
|
|
|
@ -122,18 +122,16 @@ Profuser = 1;
|
|||
Profkernel = 2;
|
||||
Proftime = 3;
|
||||
Profsample = 4;
|
||||
sizeofLock = 8;
|
||||
sizeofLock = 4;
|
||||
aggr Lock
|
||||
{
|
||||
'D' 0 key;
|
||||
'D' 4 sem;
|
||||
'D' 0 val;
|
||||
};
|
||||
|
||||
defn
|
||||
Lock(addr) {
|
||||
complex Lock addr;
|
||||
print(" key ", addr.key, "\n");
|
||||
print(" sem ", addr.sem, "\n");
|
||||
print(" val ", addr.val, "\n");
|
||||
};
|
||||
|
||||
sizeofQLp = 12;
|
||||
|
@ -152,13 +150,13 @@ QLp(addr) {
|
|||
print(" state ", addr.state, "\n");
|
||||
};
|
||||
|
||||
sizeofQLock = 20;
|
||||
sizeofQLock = 16;
|
||||
aggr QLock
|
||||
{
|
||||
Lock 0 lock;
|
||||
'D' 8 locked;
|
||||
'A' QLp 12 $head;
|
||||
'A' QLp 16 $tail;
|
||||
'D' 4 locked;
|
||||
'A' QLp 8 $head;
|
||||
'A' QLp 12 $tail;
|
||||
};
|
||||
|
||||
defn
|
||||
|
@ -172,14 +170,14 @@ QLock(addr) {
|
|||
print(" $tail ", addr.$tail\X, "\n");
|
||||
};
|
||||
|
||||
sizeofRWLock = 24;
|
||||
sizeofRWLock = 20;
|
||||
aggr RWLock
|
||||
{
|
||||
Lock 0 lock;
|
||||
'D' 8 readers;
|
||||
'D' 12 writer;
|
||||
'A' QLp 16 $head;
|
||||
'A' QLp 20 $tail;
|
||||
'D' 4 readers;
|
||||
'D' 8 writer;
|
||||
'A' QLp 12 $head;
|
||||
'A' QLp 16 $tail;
|
||||
};
|
||||
|
||||
defn
|
||||
|
@ -506,20 +504,34 @@ MINBLOCKSIZE = 32;
|
|||
complex Free checklist:t;
|
||||
complex Free checklist:q;
|
||||
complex Free checktree:t;
|
||||
complex Free ltreewalk:t;
|
||||
complex Free ltreewalk:f;
|
||||
complex Free treeinsert:tree;
|
||||
complex Free treeinsert:node;
|
||||
complex Free treeinsert:loc;
|
||||
complex Free treeinsert:repl;
|
||||
complex Free treedelete:tree;
|
||||
complex Free treedelete:node;
|
||||
complex Free treedelete:loc;
|
||||
complex Free treedelete:lsucc;
|
||||
complex Free treedelete:succ;
|
||||
complex Free treelookupgt:t;
|
||||
complex Free treelookupgt:lastgood;
|
||||
complex Free treesplay:t;
|
||||
complex Free treesplay:N;
|
||||
complex Free treesplay:l;
|
||||
complex Free treesplay:r;
|
||||
complex Free treesplay:y;
|
||||
complex Free listadd:list;
|
||||
complex Free listadd:node;
|
||||
complex Free listdelete:list;
|
||||
complex Free listdelete:node;
|
||||
complex Pool pooladd:p;
|
||||
complex Alloc pooladd:anode;
|
||||
complex Free pooladd:lst;
|
||||
complex Free pooladd:olst;
|
||||
complex Free pooladd:node;
|
||||
complex Free pooladd:root;
|
||||
complex Free pooladd:parent;
|
||||
complex Pool pooldel:p;
|
||||
complex Free pooldel:node;
|
||||
complex Free pooldel:root;
|
||||
complex Free pooldel:lst;
|
||||
complex Free pooldel:olst;
|
||||
complex Free pooldel:parent;
|
||||
complex Pool dsize2bsize:p;
|
||||
complex Pool bsize2asize:p;
|
||||
complex Pool blockmerge:pool;
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
void
|
||||
lock(Lock *lk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* once fast */
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
/* a thousand times pretty fast */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(0);
|
||||
}
|
||||
/* now nice and slow */
|
||||
for(i=0; i<1000; i++){
|
||||
if(!_tas((int*)&lk->key))
|
||||
return;
|
||||
sleep(100);
|
||||
}
|
||||
/* take your time */
|
||||
while(_tas((int*)&lk->key))
|
||||
sleep(1000);
|
||||
}
|
||||
|
||||
int
|
||||
canlock(Lock *lk)
|
||||
{
|
||||
if(_tas((int*)&lk->key))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
unlock(Lock *lk)
|
||||
{
|
||||
lk->key = 0;
|
||||
}
|
|
@ -22,7 +22,7 @@ SFILES=\
|
|||
vlop.s
|
||||
|
||||
CFILES=\
|
||||
lock.c\
|
||||
cycles.c\
|
||||
notejmp.c\
|
||||
sqrt.c\
|
||||
vlrt.c\
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue