1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/*
* Enabling and disabling interrupts setting is clearly not going
* to be very useful for running on x86 in Linux userspace, but
* mostly here just to think about what we might need for ARM
*/
.macro enable_interrupts
#ifdef SAIL_DISABLE_INTERRUPTS
sti
#endif
.endm
.macro disable_interrupts
#ifdef SAIL_DISABLE_INTERRUPTS
cli
#endif
.endm
sail_spin_unlock:
movl $1, (%rdi)
xorl %eax, %eax
enable_interrupts
ret
.globl sail_spin_unlock
/* Attempt to aquire the lock. zero flag will be set on success, otherwise set */
.macro acquire reg, mem
disable_interrupts
movl $0, \reg
xchgl \reg, \mem
cmpl $1, \reg
.endm
sail_spin_lock:
/* If the value pointed to by %rdi is equal to 0 (locked), then spin */
cmpl $0, (%rdi)
je .spin
.acquire:
acquire %eax, (%rdi)
#ifdef SAIL_DISABLE_INTERRUPTS
jnz .failed
#else
jnz .spin
#endif
xorl %eax, %eax
ret
.failed:
enable_interrupts
.spin:
pause
cmpl $0, (%rdi)
je .spin
jmp .acquire
.globl sail_spin_lock
sail_spin_trylock:
acquire %eax, (%rdi)
jnz .failed_try
xorl %eax, %eax
ret
.failed_try:
enable_interrupts
movl $1, %eax
ret
.globl sail_spin_trylock
|