diff options
Diffstat (limited to 'src/lock_acquire.asm')
-rw-r--r-- | src/lock_acquire.asm | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/src/lock_acquire.asm b/src/lock_acquire.asm index f32ba6a..8415d7f 100644 --- a/src/lock_acquire.asm +++ b/src/lock_acquire.asm @@ -43,12 +43,15 @@ section .text ; Returns zero on success, or a standard error code. global linen_lock_acquire linen_lock_acquire: + ; It's handy to have a register that's 0 during most of this function + xor esi, esi + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Check validity of argument ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Return EINVAL if rdi is NULL or otherwise invalid - mov eax, -22 ; (EINVAL = -22) + ; Return EINVAL (-22) if rdi is NULL or otherwise invalid + lea eax, [rsi - 22] ; mov eax, -22 test rdi, rdi jz acquire_return ; rdi is NULL @@ -57,8 +60,7 @@ linen_lock_acquire: ; if that assumption is wrong we'll get a segmentation fault. ; But we don't yet trust that [rdi] is a valid lock handle! ; To verify this we check the canary value stored at [rdi + 8]. - mov ecx, [rdi + 8] - cmp ecx, 0xCAFEBABE + cmp dword [rdi + 8], 0xCAFEBABE ; Oh CISC... jnz acquire_return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -70,7 +72,8 @@ linen_lock_acquire: ; See: man 2 gettid ; gettid: rax = system call ID - mov eax, SYS_GETTID + xor eax, eax + mov al, SYS_GETTID ; gettid: rax = gettid() syscall @@ -119,7 +122,7 @@ linen_lock_acquire: ; so in most real-world cases you can delete this with no downside. ; Loop counter - mov ecx, 10 + mov sil, 10 acquire_spinloop: ; The "pause" instruction is specially designed for loops like this ; and conserves power. It causes a small delay (makes sense here). @@ -133,7 +136,7 @@ linen_lock_acquire: jz acquire_success ; Decrement loop counter until zero - dec ecx + dec esi jnz acquire_spinloop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -150,24 +153,25 @@ linen_lock_acquire: ; futex: rsi = futex_op: which futex operation we want: ; - FUTEX_LOCK_PI: block until lock's owner uses FUTEX_UNLOCK_PI ; - FUTEX_PRIVATE_FLAG: this lock isn't shared with another process - mov esi, (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) + mov sil, (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) ; futex: r10 = timeout: in case we had a deadline (we don't) xor r10, r10 ; futex: rdx = val: ignored when FUTEX_LOCK_PI is used ; futex: r8 = uaddr2: ignored when FUTEX_LOCK_PI is used ; futex: r9 = val3: ignored when FUTEX_LOCK_PI is used ; futex: rax = system call ID - mov eax, SYS_FUTEX + xor eax, eax + mov al, SYS_FUTEX ; futex: rax = futex(rdi, rsi, (rdx), r10, (r8), (r9)) syscall ; Sometimes the lock is released after the "lock cmpxchg" instruction ; but just before the futex call. In that case, futex returns EAGAIN. - cmp rax, -11 ; (-EAGAIN) + cmp eax, -11 ; (-EAGAIN) je acquire_futex ; Any other negative return value means failure - test rax, rax + test eax, eax jnz acquire_return ; Indicate that we made a futex call (see below for why) |