summaryrefslogtreecommitdiff
path: root/src/lock_acquire.asm
diff options
context:
space:
mode:
authorPrefetch2023-07-24 19:21:30 +0200
committerPrefetch2023-07-24 19:21:30 +0200
commit94e3e3652f9f04810126ee754fa9a788289e2897 (patch)
treeaf5aac9f176039e97f1ebc46b497b5fd192a4fa2 /src/lock_acquire.asm
parenta211da8cfe9b0565881537cc81b09ae55c722111 (diff)
Reduce total code size by 53 bytes (big deal, right?)HEADmaster
Diffstat (limited to 'src/lock_acquire.asm')
-rw-r--r--src/lock_acquire.asm26
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)