summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/arm/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/arm/lock.c
parent3d05e77ca1f743e5b4091c6bfe311460175ed9ae (diff)
ape: change tas/sleep locks to cas/semacquire/semrelease locks (from sources)
Diffstat (limited to 'sys/src/ape/lib/ap/arm/lock.c')
-rw-r--r--sys/src/ape/lib/ap/arm/lock.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/sys/src/ape/lib/ap/arm/lock.c b/sys/src/ape/lib/ap/arm/lock.c
index 91c0ba233..65a65df7b 100644
--- a/sys/src/ape/lib/ap/arm/lock.c
+++ b/sys/src/ape/lib/ap/arm/lock.c
@@ -1,26 +1,35 @@
-#define _LOCK_EXTENSION
+#include "../plan9/lib.h"
#include "../plan9/sys9.h"
+#define _LOCK_EXTENSION
#include <lock.h>
-int tas(int*);
-
void
-lock(Lock *lk)
+lock(Lock *l)
{
- while(tas(&lk->val))
- _SLEEP(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 */
+ }
}
-int
-canlock(Lock *lk)
+void
+unlock(Lock *l)
{
- if(tas(&lk->val))
- return 0;
- return 1;
+ if(adec(&l->key) == 0)
+ return; /* changed from 1 -> 0: no contention */
+ _SEMRELEASE(&l->sem, 1);
}
-void
-unlock(Lock *lk)
+int
+canlock(Lock *l)
{
- lk->val = 0;
+ 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;
}