summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/mips/lock.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-09-21 19:55:52 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-09-21 19:55:52 +0200
commitf811708ffcb776be52a81637224c06b700177566 (patch)
tree05a9632fef0f4e5ad835c2e6d426631e485e90d1 /sys/src/ape/lib/ap/mips/lock.c
parent3d05e77ca1f743e5b4091c6bfe311460175ed9ae (diff)
ape: change tas/sleep locks to cas/semacquire/semrelease locks (from sources)
Diffstat (limited to 'sys/src/ape/lib/ap/mips/lock.c')
-rw-r--r--sys/src/ape/lib/ap/mips/lock.c178
1 files changed, 21 insertions, 157 deletions
diff --git a/sys/src/ape/lib/ap/mips/lock.c b/sys/src/ape/lib/ap/mips/lock.c
index 866d074e9..65a65df7b 100644
--- a/sys/src/ape/lib/ap/mips/lock.c
+++ b/sys/src/ape/lib/ap/mips/lock.c
@@ -1,171 +1,35 @@
-#define _LOCK_EXTENSION
-#include <stdlib.h>
-#include <string.h>
+#include "../plan9/lib.h"
#include "../plan9/sys9.h"
+#define _LOCK_EXTENSION
#include <lock.h>
-enum
-{
- 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)
+lock(Lock *l)
{
- 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;
- }
+ 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 */
+ }
}
void
-unlock(Lock *lk)
+unlock(Lock *l)
{
- lk->val = 0;
+ if(adec(&l->key) == 0)
+ return; /* changed from 1 -> 0: no contention */
+ _SEMRELEASE(&l->sem, 1);
}
int
-tas(int *p)
+canlock(Lock *l)
{
- 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;
- }
+ 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;
}