Tvùrce webu je i pro tebe! Postav tøeba web. Bez grafika. Bez kodéra. Hned.
wz

RWLOCK.ASM

Read/Write Spin-lock


; =============================================================================
;
;                         Litos - Read/write spin-lock
;
; =============================================================================
; Read/write spin-lock is used to lock bus between processors to allow one
; writer OR multiple readers.
; =============================================================================

		CODE_SECTION	32

; Currently not used - locked places are very short, it would not be efficient.

%ifdef _UNUSED_


RWSPIN_BIAS	EQU	01000000h	; bias for writer

%define		RWLOCK  dd  RWSPIN_BIAS	; macro - initialized r/w spin-lock

%ifdef	SMP

; -----------------------------------------------------------------------------
;                     Initialize read/write spin-lock
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; -----------------------------------------------------------------------------

RWSpinInit:	mov	dword [ebx],RWSPIN_BIAS	; init read/write spin-lock
		ret

; -----------------------------------------------------------------------------
;                    Lock read/write spin-lock for reading
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; NOTES:	Entry point is RWReadLock label.
; -----------------------------------------------------------------------------

; ------------- Return old value of read/write spin-lock

RWReadLock2:	lock			; CPU instruction lock
		inc	dword [ebx]	; return old value of the spin-lock

; ------------- Wait for releasing read/write spin-lock

RWReadLock4:	rep	nop		; CPU optimise hint (=Pentium 4 pause)
		cmp	dword [ebx],byte 0 ; is the lock still locked?
		jle	RWReadLock4	; wait for releasing the lock

; ------------- Try to lock for reading

RWReadLock:	lock			; CPU instruction lock
		dec	dword [ebx]	; try to lock for reading
		js	RWReadLock2	; read/write lock is locked for writing
		ret

; -----------------------------------------------------------------------------
;                    Lock read/write spin-lock for writing
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; NOTES:	Entry point is RWWriteLock label.
; -----------------------------------------------------------------------------

; ------------- Return old value of read/write spin-lock

RWWriteLock2:	lock			; CPU instruction lock
		add	dword [ebx],RWSPIN_BIAS	; return old value of the lock

; ------------- Wait for releasing read/write spin-lock

RWWriteLock4:	rep	nop		; CPU optimise hint (=Pentium 4 pause)
		cmp	dword [ebx],RWSPIN_BIAS; is the lock still locked?
		jne	RWWriteLock4	; wait for releasing the lock

; ------------- Try to lock for reading

RWWriteLock:	lock			; CPU instruction lock
		sub	dword [ebx],RWSPIN_BIAS	; try to lock for writing
		jnz	RWWriteLock2	; read/write lock is already locked
		ret

; -----------------------------------------------------------------------------
;               Unlock read/write spin-lock locked for reading
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; -----------------------------------------------------------------------------

RWReadUnlock:	lock			; CPU instruction lock
		inc	dword [ebx]	; return old value of the spin-lock
		ret

; -----------------------------------------------------------------------------
;               Unlock read/write spin-lock locked for writing
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; -----------------------------------------------------------------------------

RWWriteUnlock:	lock			; CPU instruction lock
		add	dword [ebx],RWSPIN_BIAS	; return old value of the lock
		ret

; -----------------------------------------------------------------------------
;                 Try to lock read/write spin-lock for reading
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; OUTPUT:	EAX = 1 (successfully locked) or 0 (the lock is already locked)
;		ZY = spin-lock was successfully locked for reading (EAX = 1)
; -----------------------------------------------------------------------------

RWReadTryLock:	xor	eax,eax		; EAX <- 0
		lock			; CPU instruction lock
		dec	dword [ebx]	; try to lock for reading
		setns	al		; AL <- 1 locked, 0 error
		jns	RWReadTryLock2	; locked
		lock			; CPU instruction lock
		inc	dword [ebx]	; return old value of the spin-lock
RWReadTryLock2:	cmp	al,1		; test state (1=locked, 0=error)
		ret

; -----------------------------------------------------------------------------
;                 Try to lock read/write spin-lock for writing
; -----------------------------------------------------------------------------
; INPUT:	EBX = read/write spin-lock entry
; OUTPUT:	EAX = 1 (successfully locked) or 0 (the lock is already locked)
;		ZY = spin-lock was successfully locked for writing (EAX = 1)
; -----------------------------------------------------------------------------

RWWriteTryLock:	xor	eax,eax		; EAX <- 0
		lock			; CPU instruction lock
		sub	dword [ebx],RWSPIN_BIAS	; try to lock for writing
		setz	al		; AL <- 1 locked, 0 error
		jz	RWWriteTryLock2	; locked
		lock			; CPU instruction lock
		add	dword [ebx],RWSPIN_BIAS	; return old value of the lock
RWWriteTryLock2:cmp	al,1		; test state (1=locked, 0=error)
		ret

; -----------------------------------------------------------------------------
;             Test if read/write spin-lock can be locked for reading
; -----------------------------------------------------------------------------
; INPUT:	EBX = spin-lock entry
; OUTPUT:	EAX = 1 (can be locked) or 0 (is already locked)
;		ZY = spin-lock can be locked for reading (EAX = 1)
; -----------------------------------------------------------------------------

RWReadTest:	xor	eax,eax		; EAX <- 0
		cmp	dword [ebx],byte 0 ; can be locked?
		setg	al		; EAX <- 1 can be locked, 0 cannot
		cmp	al,1		; test state
		ret

; -----------------------------------------------------------------------------
;             Test if read/write spin-lock can be locked for writing
; -----------------------------------------------------------------------------
; INPUT:	EBX = spin-lock entry
; OUTPUT:	EAX = 1 (can be locked) or 0 (is already locked)
;		ZY = spin-lock can be locked for writing (EAX = 1)
; -----------------------------------------------------------------------------

RWWriteTest:	xor	eax,eax		; EAX <- 0
		cmp	dword [ebx],RWSPIN_BIAS ; can be locked?
		sete	al		; EAX <- 1 can be locked, 0 cannot
		ret

%endif  ; SMP


%endif  ; _UNUSED_

Back to source browser