diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-09-26 22:24:31 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-09-26 22:24:31 +0200 |
commit | cdc2c30e99f2fb3d65dfbc8ef73efd433a3f1966 (patch) | |
tree | 5c3d5a6a42311f09444ca34d09bfebc78e08f5a3 /sys/src/libc/mips | |
parent | b4cdfc6c5517390d6be05b2c01e56bacc9e85ea8 (diff) |
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.
Diffstat (limited to 'sys/src/libc/mips')
-rw-r--r-- | sys/src/libc/mips/atom.s | 13 | ||||
-rw-r--r-- | sys/src/libc/mips/lock.c | 171 | ||||
-rw-r--r-- | sys/src/libc/mips/mkfile | 1 | ||||
-rw-r--r-- | sys/src/libc/mips/tas.s | 1 |
4 files changed, 181 insertions, 5 deletions
diff --git a/sys/src/libc/mips/atom.s b/sys/src/libc/mips/atom.s index b907f7f59..8975ac569 100644 --- a/sys/src/libc/mips/atom.s +++ b/sys/src/libc/mips/atom.s @@ -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 diff --git a/sys/src/libc/mips/lock.c b/sys/src/libc/mips/lock.c new file mode 100644 index 000000000..9c9bd2208 --- /dev/null +++ b/sys/src/libc/mips/lock.c @@ -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; +} diff --git a/sys/src/libc/mips/mkfile b/sys/src/libc/mips/mkfile index 460f7cd2f..3b902f6e3 100644 --- a/sys/src/libc/mips/mkfile +++ b/sys/src/libc/mips/mkfile @@ -23,6 +23,7 @@ SFILES=\ CFILES=\ cycles.c\ + lock.c\ notejmp.c\ sqrt.c\ vlrt.c\ diff --git a/sys/src/libc/mips/tas.s b/sys/src/libc/mips/tas.s index a9bf40721..d754b21f6 100644 --- a/sys/src/libc/mips/tas.s +++ b/sys/src/libc/mips/tas.s @@ -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: |