home *** CD-ROM | disk | FTP | other *** search
-
- section text,CODE
-
- xref _SysBase
-
- xref _LVOSignal
- xref _LVOForbid
- xref _LVOPermit
- xref _LVOWait
- xref _LVOFindTask
-
- xdef _LockAddr
- xdef _LockAddrB
- xdef _TryLockAddr
- xdef _TryLockAddrB
- xdef _UnlockAddr
- xdef _UnlockAddrB
-
- _TryLockAddrB: movem.l 4(sp),D0/A0
- bra TLA0
- _TryLockAddr:
- move.l 4(sp),A0
- moveq.l #0,D0
-
- TLA0: 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
-
- _LockAddrB: movem.l 4(sp),D0/A0 ; bit: D0 lock: A0
- bra LA0
- _LockAddr: ; bit: 0 lock: A0
- move.l 4(sp),A0
-
- ; MAIN LOCK CODE
-
- moveq.l #0,D0
- LA0: bset.b D0,4(A0) ; attempt to gain lock
- bne la10 ; failure
- rts ; success, done, rts (FAST)
-
- la10 movem.l D2/A2/A6,-(sp) ; failure (SLOW) (BLOCK)
- move.l _SysBase,A6 ; A6 = SYSBase
- movem.l D0/A0,-(sp)
- sub.l A1,A1
- jsr _LVOFindTask(A6)
- move.l D0,D2
- jsr _LVOForbid(A6)
- movem.l (sp)+,D0/A0
- 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 D2,-(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
- jsr _LVOPermit(A6)
- movem.l (sp)+,D2/A2/A6
- rts
-
- xdef _UnlockAddr
- xdef _UnlockAddrB
-
- _UnlockAddrB: movem.l 4(sp),D0/A0
- bra UL0
- _UnlockAddr: move.l 4(sp),A0
- moveq.l #0,D0
-
- UL0: bclr.b D0,4(A0) ; clear lock bit
- move.l (A0),D1 ; anybody waiting?
- beq ulrts ; no, rts
- ULW:
- movem.l D2/A2/A6,-(sp) ; yes, wake 'm all up
- move.b D0,D2 ; D2 = bit#
- move.l _SysBase,A6 ; A6 = SYSBase
- movem.l D0/A0,-(sp)
- jsr _LVOForbid(A6)
- movem.l (sp)+,D0/A0
-
- 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
- jsr _LVOPermit(A6)
- movem.l (sp)+,D2/A2/A6
- ulrts rts
-
- END
-
-