tighten up the spinlock loop, and some other bikeshedding
Former-commit-id: 8bd56fadd6e73794415e1f9eae892c772800e559
This commit is contained in:
parent
2cb187ce0a
commit
c8e0070fd4
@ -25,28 +25,21 @@ fastlock_lock:
|
|||||||
mov rdi, [rsp] ; get our pointer back
|
mov rdi, [rsp] ; get our pointer back
|
||||||
|
|
||||||
cmp [rdi+4], esi ; Is the TID we got back the owner of the lock?
|
cmp [rdi+4], esi ; Is the TID we got back the owner of the lock?
|
||||||
je .LRecursive ; Don't spin in that case
|
je .LLocked ; Don't spin in that case
|
||||||
|
|
||||||
xor eax, eax ; eliminate partial register dependency
|
xor eax, eax ; eliminate partial register dependency
|
||||||
mov ax, 1 ; we want to add one
|
inc eax ; we want to add one
|
||||||
lock xadd [rdi+2], ax ; do the xadd, ax contains the value before the addition
|
lock xadd [rdi+2], ax ; do the xadd, ax contains the value before the addition
|
||||||
; eax now contains the ticket
|
; eax now contains the ticket
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
ALIGN 16
|
ALIGN 16
|
||||||
.Loop:
|
.LLoop:
|
||||||
cmp [rdi], ax ; is our ticket up?
|
cmp [rdi], ax ; is our ticket up?
|
||||||
je .LDone ; leave the loop
|
je .LLocked ; leave the loop
|
||||||
|
pause
|
||||||
add ecx, 1000h ; Have we been waiting a long time? (oflow if we have)
|
add ecx, 1000h ; Have we been waiting a long time? (oflow if we have)
|
||||||
; 1000h is set so we overflow on the 1024*1024'th iteration (like the C code)
|
; 1000h is set so we overflow on the 1024*1024'th iteration (like the C code)
|
||||||
jc .LYield ; If so, give up our timeslice to someone who's doing real work
|
jnc .LLoop ; If so, give up our timeslice to someone who's doing real work
|
||||||
pause ; be nice to other hyperthreads
|
|
||||||
jmp .Loop ; maybe next time we'll get our turn
|
|
||||||
.LDone:
|
|
||||||
mov [rdi+4], esi ; lock->m_pidOwner = gettid()
|
|
||||||
mov dword [rdi+8], 1 ; lock->m_depth = 1
|
|
||||||
add rsp, 8 ; fix stack
|
|
||||||
ret
|
|
||||||
.LYield:
|
|
||||||
; Like the compiler, you're probably thinking: "Hey! I should take these pushs out of the loop"
|
; Like the compiler, you're probably thinking: "Hey! I should take these pushs out of the loop"
|
||||||
; But the compiler doesn't know that we rarely hit this, and when we do we know the lock is
|
; But the compiler doesn't know that we rarely hit this, and when we do we know the lock is
|
||||||
; taking a long time to be released anyways. We optimize for the common case of short
|
; taking a long time to be released anyways. We optimize for the common case of short
|
||||||
@ -59,10 +52,12 @@ ALIGN 16
|
|||||||
pop rsi
|
pop rsi
|
||||||
mov rdi, [rsp] ; our struct pointer is on the stack already
|
mov rdi, [rsp] ; our struct pointer is on the stack already
|
||||||
xor ecx, ecx ; Reset our loop counter
|
xor ecx, ecx ; Reset our loop counter
|
||||||
jmp .Loop ; Get back in the game
|
jmp .LLoop ; Get back in the game
|
||||||
.LRecursive:
|
ALIGN 16
|
||||||
add dword [rdi+8], 1 ; increment the depth counter
|
.LLocked:
|
||||||
add rsp, 8 ; fix the stack
|
mov [rdi+4], esi ; lock->m_pidOwner = gettid()
|
||||||
|
inc dword [rdi+8] ; lock->m_depth++
|
||||||
|
add rsp, 8 ; fix stack
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ALIGN 16
|
ALIGN 16
|
||||||
@ -93,14 +88,18 @@ fastlock_trylock:
|
|||||||
add ecx, 10000h ; increment avail, ecx is now our wanted value
|
add ecx, 10000h ; increment avail, ecx is now our wanted value
|
||||||
lock cmpxchg [rdi], ecx ; If rdi still contains the value in eax, put in ecx (inc avail)
|
lock cmpxchg [rdi], ecx ; If rdi still contains the value in eax, put in ecx (inc avail)
|
||||||
jnz .LAlreadyLocked ; If Z is not set then someone locked it while we were preparing
|
jnz .LAlreadyLocked ; If Z is not set then someone locked it while we were preparing
|
||||||
mov eax, 1 ; return SUCCESS!
|
xor eax, eax
|
||||||
|
inc eax ; return SUCCESS! (eax=1)
|
||||||
mov [rdi+4], esi ; lock->m_pidOwner = gettid()
|
mov [rdi+4], esi ; lock->m_pidOwner = gettid()
|
||||||
mov dword [rdi+8], eax ; lock->m_depth = 1
|
mov dword [rdi+8], eax ; lock->m_depth = 1
|
||||||
ret
|
ret
|
||||||
.LAlreadyLocked:
|
ALIGN 16
|
||||||
xor eax, eax ; return 0 for failure
|
|
||||||
ret
|
|
||||||
.LRecursive:
|
.LRecursive:
|
||||||
add dword [rdi+8], 1 ; increment the depth counter
|
xor eax, eax
|
||||||
mov eax, 1 ; we successfully got the lock
|
inc eax ; return SUCCESS! (eax=1)
|
||||||
|
inc dword [rdi+8] ; lock->m_depth++
|
||||||
|
ret
|
||||||
|
ALIGN 16
|
||||||
|
.LAlreadyLocked:
|
||||||
|
xor eax, eax ; return 0;
|
||||||
ret
|
ret
|
Loading…
x
Reference in New Issue
Block a user