BITS 32

; Adapted from... Wikipedia ¯\(o_º)/¯

global spin_init
spin_init:
	push ebp
	mov ebp, esp
	
	mov ecx, [ebp + 8] ; [ecx] is now lock
	
	mov long [ecx], 0 ; lock initially unlocked

	pop ebp
	ret

global spin_lock
spin_lock:
	push ebp
	mov ebp, esp

	mov ecx, [ebp + 8]

	mov eax, 1 ; = locked

	xchg eax, [ecx]

	test eax, eax
	jz .acquired

	; didn't get the lock on the first try...
	; deplete this processes timeslice

	; or something

.spin
	xchg eax, [ecx] ; atomic

	test eax, eax
	jnz .spin ; did we just acquire the lock?
.acquired

	pop ebp
	ret

global spin_unlock
spin_unlock:
	push ebp
	mov ebp, esp
	
	mov ecx, [ebp + 8]

	mov eax, 0 ; = unlocked
	xchg eax, [ecx] ; atomic
	
	pop ebp
	ret
