home *** CD-ROM | disk | FTP | other *** search
-
- ; long var[2] = { 0, 0 };
- ;
- ; These routines provide fast exclusive
- ; locks.
- ;
- ; LockAddr(&var[0]:A0)
- ; UnlockAddr(&var[0]:A0)
- ; TryLockAddr(&var[0]:A0)
-
- section __MERGED,DATA
-
- xref _SysBase
-
- section text,CODE
-
- include "exec/types.i"
- include "exec/ports.i"
- include "exec/tasks.i"
- include "exec/execbase.i"
- include "exec/ables.i"
- include "exec/memory.i"
-
- xref _LVOWait
- xref _LVOForbid
- xref _LVOPermit
- xref _LVOSignal
-
- xdef _LockAddr
- xdef _UnlockAddr
- xdef _TryLockAddr
-
- _TryLockAddr:
- move.l 4(sp),A0
- moveq.l #0,D0
-
- bset.b D0,4(A0) ; attempt to gain lock
- bne .tla10 ; failure
- moveq.l #1,D0
- rts ; success, return 1
- .tla10 moveq.l #-1,D0 ; failure, return -1
- rts
-
- _LockAddr: ; bit: 0 lock: A0
- move.l 4(sp),A0
- moveq.l #0,D0
-
- bset.b D0,4(A0) ; attempt to gain lock
- bne .la10 ; failure
- rts ; success, done, rts (FAST)
-
- .la10 movem.l A2/A6,-(sp) ; failure (SLOW) (BLOCK)
- move.l _SysBase,A6 ; A6 = SYSBase
- FORBID
- bset.b D0,4(A0) ; try again after FORBID
- beq .la20 ; got it!
-
- ; Put linked list structure on stack
-
- move.w D0,-(sp) ; bit# 12(sp)
- move.l ThisTask(A6),-(sp) ; task# 8(sp)
- move.l A0,-(sp) ; &var 4(sp)
- move.l (A0),-(sp) ; Next (sp)
- move.l sp,(A0) ; (put at head of list)
-
- ; Loop Wait/re-attempt lock
-
- .la15 moveq.l #$10,D0 ; wait (semaphore signal)
- jsr _LVOWait(A6)
-
- move.w 12(sp),D0 ; try for lock
- move.l 4(sp),A0
- bset.b D0,4(A0)
- bne .la15 ; loop until get it
-
- .la16 cmp.l (A0),sp ; unlink, find our node!
- beq .la18
- move.l (A0),A0
- bra .la16
- .la18 move.l (sp),(A0)
- add.w #14,sp
- .la20
- PERMIT
- movem.l (sp)+,A2/A6
- rts
-
- _UnlockAddr: move.l 4(sp),A0
- moveq.l #0,D0
-
- bclr.b D0,4(A0) ; clear lock bit
- move.l (A0),D1 ; anybody waiting?
- beq .ulrts ; no, rts
-
- movem.l D2/A2/A6,-(sp) ; yes, wake 'm all up
- move.b D0,D2 ; D2 = bit#
- move.l _SysBase,A6 ; A6 = SYSBase
- FORBID
-
- move.l (A0),D1 ; get pointer again after FORBID
- beq .ul20 ; no, rts (close a window)
-
- .ul10 move.l D1,A2 ; A2 = node
- cmp.b 13(A2),D2 ; waiting on our bit #?
- bne .ul18 ; no
- move.l 8(A2),A1 ; yes, signal the node
- moveq.l #$10,D0
- jsr _LVOSignal(A6) ; signal EVERYONE waiting
- .ul18 move.l (A2),D1 ; next
- bne .ul10
-
- .ul20
- PERMIT
- movem.l (sp)+,D2/A2/A6
- .ulrts rts
-
-
- END
-