aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9/lock.c')
-rw-r--r--src/lib9/lock.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/lib9/lock.c b/src/lib9/lock.c
new file mode 100644
index 00000000..2da73626
--- /dev/null
+++ b/src/lib9/lock.c
@@ -0,0 +1,54 @@
+#include <unistd.h>
+#include <sched.h>
+#include <lib9.h>
+
+int _ntas;
+static int
+_xtas(void *v)
+{
+ int x;
+
+_ntas++;
+ x = _tas(v);
+ if(x == 0 || x == 0xCAFEBABE)
+ return x;
+ fprint(2, "%d: tas %p got %ux\n", getpid(), v, x);
+ abort();
+}
+
+int
+canlock(Lock *l)
+{
+ return !_xtas(&l->val);
+}
+
+void
+unlock(Lock *l)
+{
+ l->val = 0;
+}
+
+void
+lock(Lock *lk)
+{
+ int i;
+
+ /* once fast */
+ if(!_xtas(&lk->val))
+ return;
+ /* a thousand times pretty fast */
+ for(i=0; i<1000; i++){
+ if(!_xtas(&lk->val))
+ return;
+ sched_yield();
+ }
+ /* now nice and slow */
+ for(i=0; i<1000; i++){
+ if(!_xtas(&lk->val))
+ return;
+ usleep(100*1000);
+ }
+ /* take your time */
+ while(_xtas(&lk->val))
+ usleep(1000*1000);
+}