summaryrefslogtreecommitdiff
path: root/os/port/taslock.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/port/taslock.c')
-rw-r--r--os/port/taslock.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/os/port/taslock.c b/os/port/taslock.c
new file mode 100644
index 00000000..7914b80a
--- /dev/null
+++ b/os/port/taslock.c
@@ -0,0 +1,126 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+static void
+lockloop(Lock *l, ulong pc)
+{
+ setpanic();
+ print("lock loop 0x%lux key 0x%lux pc 0x%lux held by pc 0x%lux\n", l, l->key, pc, l->pc);
+ panic("lockloop");
+}
+
+void
+lock(Lock *l)
+{
+ int i;
+ ulong pc;
+
+ pc = getcallerpc(&l);
+ if(up == 0) {
+ if (_tas(&l->key) != 0) {
+ for(i=0; ; i++) {
+ if(_tas(&l->key) == 0)
+ break;
+ if (i >= 1000000) {
+ lockloop(l, pc);
+ break;
+ }
+ }
+ }
+ l->pc = pc;
+ return;
+ }
+
+ for(i=0; ; i++) {
+ if(_tas(&l->key) == 0)
+ break;
+ if (i >= 1000) {
+ lockloop(l, pc);
+ break;
+ }
+ if(conf.nmach == 1 && up->state == Running && islo()) {
+ up->pc = pc;
+ sched();
+ }
+ }
+ l->pri = up->pri;
+ up->pri = PriLock;
+ l->pc = pc;
+}
+
+void
+ilock(Lock *l)
+{
+ ulong x, pc;
+ int i;
+
+ pc = getcallerpc(&l);
+ x = splhi();
+ for(;;) {
+ if(_tas(&l->key) == 0) {
+ l->sr = x;
+ l->pc = pc;
+ return;
+ }
+ if(conf.nmach < 2)
+ panic("ilock: no way out: pc 0x%lux: lock 0x%lux held by pc 0x%lux", pc, l, l->pc);
+ for(i=0; ; i++) {
+ if(l->key == 0)
+ break;
+ clockcheck();
+ if (i > 100000) {
+ lockloop(l, pc);
+ break;
+ }
+ }
+ }
+}
+
+int
+canlock(Lock *l)
+{
+ if(_tas(&l->key))
+ return 0;
+ if(up){
+ l->pri = up->pri;
+ up->pri = PriLock;
+ }
+ l->pc = getcallerpc(&l);
+ return 1;
+}
+
+void
+unlock(Lock *l)
+{
+ int p;
+
+ if(l->key == 0)
+ print("unlock: not locked: pc %lux\n", getcallerpc(&l));
+ p = l->pri;
+ l->pc = 0;
+ l->key = 0;
+ coherence();
+ if(up){
+ up->pri = p;
+ if(up->state == Running && anyhigher())
+ sched();
+ }
+}
+
+void
+iunlock(Lock *l)
+{
+ ulong sr;
+
+ if(l->key == 0)
+ print("iunlock: not locked: pc %lux\n", getcallerpc(&l));
+ sr = l->sr;
+ l->pc = 0;
+ l->key = 0;
+ coherence();
+ splxpc(sr);
+}