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

SPINLOCK.ASM

Spin-lock


; =============================================================================
;
;                             Litos - Spin-lock
;
; =============================================================================
; Spin-lock is used to lock bus between processors to avoid read partially
; modified variable. Spin-lock is a byte with value 1 (spin-lock is unlocked),
; 0 (any CPU has this spin-lock locked) or < 0 (another CPU tries for lock).
; Spin-lock supports 127 CPUs maximal. Spin-lock cannot be locket more times
; in the same CPU, so it should be used with interrupt disabled (to avoid
; task switching during lock).
; =============================================================================

		CODE_SECTION	32

%define		SPINLOCK  dd	1	; macro - initialized spin-lock

%ifdef	SMP

; ------------- Macro - initialize spin-lock (%1 = pointer, uses EAX)

%macro		LOCK_Init 1
		xor	eax,eax		; EAX <- 0
		inc	eax		; EAX <- 1
		mov	[%1],eax	; init spin-lock
%endmacro

; ------------- Macro - initialize spin-lock (%1=pointer, EAX=0, output EAX=1)

%macro		LOCK0_Init 1
		inc	eax		; EAX <- 1
		mov	[%1],eax	; init spin-lock
%endmacro

; ------------- Macro - initialize spin-lock (%1=pointer, EAX=1)

%macro		LOCK1_Init 1
		mov	[%1],eax	; init spin-lock
%endmacro

; ------------- Macro - initialize spin-lock (%1 = pointer)

%macro		LOCK2_Init 1
		mov	dword [%1],1	; init spin-lock
%endmacro

; ------------- Macro - initialize spin-lock from zero value (%1 = pointer)

%macro		LOCK3_Init 1
		inc	dword [%1]	; init spin-lock
%endmacro

; ------------- Macro - initialize spin-lock locked (%1=pointer)

%macro		LOCK_InitLock 1
		and	dword [%1],byte 0
%endmacro

; ------------- Macro - lock spin-lock (%1=pointer or address)

%macro		LOCK_Lock 1
				; --- Try to lock spin-lock
%%L1:		lock			; CPU instruction lock
		dec	byte [%1]	; decrease spin-lock
		jz	%%L3		; spin-lock is not locked
				; --- Wait for unlocking spin-lock
%%L2:		cmp	byte [%1],1	; is spin-lock locked?
		rep	nop		; CPU optimise hint (=Pentium 4 pause)
		jne	%%L2		; spin-lock is locked, wait for unlock
		jmp	short %%L1	; next try to lock spin-lock
%%L3:
%endmacro

; ------------- Macro - lock spin-lock function (%1=label, %2=register or address)

%macro		LOCK_LockFnc 2
				; --- Wait fot unlocking spin-lock
%%L1:		cmp	byte [%2],1	; is spin-lock locked?
		rep	nop		; CPU optimise hint (=Pentium 4 pause)
		jne	%%L1		; spin-lock is locked, wait for unlock
				; --- Try to lock spin-lock
%1:		lock			; CPU instruction lock
		dec	byte [%2]	; decrease spin-lock
		jnz	%%L1		; spin-lock is already locked
		ret			; else it got spin-lock
%endmacro

; ------------- Macro - unlock spin-lock (%1=pointer or address, saves FLAGS)

%macro		LOCK_Unlock 1
		mov	byte [%1],1	; unlock spin-lock
%endmacro

; -----------------------------------------------------------------------------
;                       Initialize/Unlock spin-lock
; -----------------------------------------------------------------------------
; INPUT:	EBX = spin-lock entry
; NOTES:	To initialize use SpinInit entry point.
;		To unlock use SpinUnlock entry point.
; -----------------------------------------------------------------------------

SpinInit:	and	dword [ebx],byte 0 ; set spin-lock to 0
SpinUnlock:	mov	byte [ebx],1	; unlock spin-lock
		ret

; -----------------------------------------------------------------------------
;                              Lock spin-lock
; -----------------------------------------------------------------------------
; INPUT:	EBX = spin-lock entry
; NOTES:	Entry point is SpinLock label.
; -----------------------------------------------------------------------------

		LOCK_LockFnc SpinLock,ebx

; -----------------------------------------------------------------------------
;                             Lock spin-lock (EAX)
; -----------------------------------------------------------------------------
; INPUT:	EAX = spin-lock entry
; NOTES:	Entry point is SpinLockEAX label.
; -----------------------------------------------------------------------------

		LOCK_LockFnc SpinLockEAX,eax

; -----------------------------------------------------------------------------
;                             Lock spin-lock (EDX)
; -----------------------------------------------------------------------------
; INPUT:	EDX = spin-lock entry
; NOTES:	Entry point is SpinLockEDX label.
; -----------------------------------------------------------------------------

		LOCK_LockFnc SpinLockEDX,edx

; -----------------------------------------------------------------------------
;                             Lock spin-lock (ESI)
; -----------------------------------------------------------------------------
; INPUT:	ESI = spin-lock entry
; NOTES:	Entry point is SpinLockESI label.
; -----------------------------------------------------------------------------

		LOCK_LockFnc SpinLockESI,esi

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

SpinTryLock:	xor	eax,eax		; EAX <- 0, locked value
		xchg	al,[ebx]	; try to lock spin-lock
		cmp	al,1		; is spin-lock locked?
		sete	al		; EAX <- 1 success, 0 already locked
		ret

%endif  ; SMP

Back to source browser