summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/mips
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-09-26 22:24:31 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-09-26 22:24:31 +0200
commitcdc2c30e99f2fb3d65dfbc8ef73efd433a3f1966 (patch)
tree5c3d5a6a42311f09444ca34d09bfebc78e08f5a3 /sys/src/ape/lib/ap/mips
parentb4cdfc6c5517390d6be05b2c01e56bacc9e85ea8 (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/ape/lib/ap/mips')
-rw-r--r--sys/src/ape/lib/ap/mips/atom.s52
-rw-r--r--sys/src/ape/lib/ap/mips/lock.c178
-rw-r--r--sys/src/ape/lib/ap/mips/mkfile1
-rw-r--r--sys/src/ape/lib/ap/mips/tas.s1
4 files changed, 157 insertions, 75 deletions
diff --git a/sys/src/ape/lib/ap/mips/atom.s b/sys/src/ape/lib/ap/mips/atom.s
deleted file mode 100644
index b907f7f59..000000000
--- a/sys/src/ape/lib/ap/mips/atom.s
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * R4000 user-level atomic operations
- */
-
-#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16))
-#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16))
-#define NOOP WORD $0x27
-
-TEXT ainc(SB), 1, $-4 /* long ainc(long *); */
-TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */
- MOVW R1, R2 /* address of counter */
-loop: MOVW $1, R3
- LL(2, 1)
- NOOP
- ADDU R1, R3
- MOVW R3, R1 /* return new value */
- SC(2, 3)
- NOOP
- BEQ R3,loop
- RET
-
-TEXT adec(SB), 1, $-4 /* long adec(long*); */
-TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */
- MOVW R1, R2 /* address of counter */
-loop1: MOVW $-1, R3
- LL(2, 1)
- NOOP
- ADDU R1, R3
- MOVW R3, R1 /* return new value */
- SC(2, 3)
- NOOP
- BEQ R3,loop1
- RET
-
-/*
- * int cas(uint* p, int ov, int nv);
- */
-TEXT cas(SB), 1, $-4
- MOVW ov+4(FP), R2
- MOVW nv+8(FP), R3
-spincas:
- LL(1, 4) /* R4 = *R1 */
- NOOP
- BNE R2, R4, fail
- SC(1, 3) /* *R1 = R3 */
- NOOP
- BEQ R3, spincas /* R3 == 0 means store failed */
- MOVW $1, R1
- RET
-fail:
- MOVW $0, R1
- RET
diff --git a/sys/src/ape/lib/ap/mips/lock.c b/sys/src/ape/lib/ap/mips/lock.c
index 65a65df7b..866d074e9 100644
--- a/sys/src/ape/lib/ap/mips/lock.c
+++ b/sys/src/ape/lib/ap/mips/lock.c
@@ -1,35 +1,171 @@
-#include "../plan9/lib.h"
-#include "../plan9/sys9.h"
#define _LOCK_EXTENSION
+#include <stdlib.h>
+#include <string.h>
+#include "../plan9/sys9.h"
#include <lock.h>
-void
-lock(Lock *l)
+enum
{
- 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 */
+ Pagesize = 4096,
+ Semperpg = Pagesize/(16*sizeof(unsigned int)),
+ 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)
+{
+ int n;
+
+ if(arch != 0)
+ return; /* allow multiple calls */
+ arch = C_fcr0();
+ switch(arch) {
+ case POWER:
+ if(_SEGATTACH(0, "lock", (void*)Lockaddr, Pagesize) == (void*)-1) {
+ arch = MAGNUM;
+ break;
+ }
+ memset((void*)Lockaddr, 0, Pagesize);
+ break;
+ case MAGNUM:
+ case MAGNUMII:
+ case R4K:
+ break;
+ default:
+ abort();
}
+
+}
+
+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;
+ }
+ }
+ return 0;
+ }
}
void
-unlock(Lock *l)
+unlock(Lock *lk)
{
- if(adec(&l->key) == 0)
- return; /* changed from 1 -> 0: no contention */
- _SEMRELEASE(&l->sem, 1);
+ lk->val = 0;
}
int
-canlock(Lock *l)
+tas(int *p)
{
- 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;
+ 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;
+ }
+ }
+ return 1;
+ }
}
diff --git a/sys/src/ape/lib/ap/mips/mkfile b/sys/src/ape/lib/ap/mips/mkfile
index 5d24b767f..0896229a6 100644
--- a/sys/src/ape/lib/ap/mips/mkfile
+++ b/sys/src/ape/lib/ap/mips/mkfile
@@ -2,7 +2,6 @@ APE=/sys/src/ape
<$APE/config
LIB=/$objtype/lib/ape/libap.a
OFILES=\
- atom.$O\
cycles.$O\
getfcr.$O\
lock.$O\
diff --git a/sys/src/ape/lib/ap/mips/tas.s b/sys/src/ape/lib/ap/mips/tas.s
index 448cbe068..d754b21f6 100644
--- a/sys/src/ape/lib/ap/mips/tas.s
+++ b/sys/src/ape/lib/ap/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: