diff options
Diffstat (limited to 'os/port/taslock.c')
| -rw-r--r-- | os/port/taslock.c | 126 |
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); +} |
