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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
/** @file sync_asm.S
*
* @brief locks.
*
* @author Hanjie Wu (hanjiew)
* @bug No functional bugs
*/
.text
#define EFL_IF 0x00000200
.global save_clear_if
.type save_clear_if, %function
save_clear_if:
pushf
pop %eax
cli
ret
.global restore_if
.type restore_if, %function
restore_if:
mov 0x4(%esp), %eax
push %eax
popf
ret
.global spl_lock
.type spl_lock, %function
spl_lock:
push %ebx
pushf
pop %ebx
cli
mov 0x8(%esp), %ecx
mov $1, %edx
.spl_lock_try:
mov (%ecx), %eax
test %eax, %eax
jnz .spl_lock_try
lock cmpxchg %edx, (%ecx)
test %eax, %eax
jnz .spl_lock_try
mov %ebx, %eax
pop %ebx
ret
.global spl_unlock
.type spl_unlock, %function
spl_unlock:
mov 0x8(%esp), %eax
mov 0x4(%esp), %ecx
xor %edx, %edx
mov %edx, (%ecx)
push %eax
popf
ret
.global yield_to_spl_unlock
.type yield_to_spl_unlock, %function
yield_to_spl_unlock:
mov 0xc(%esp), %edx
mov 0x8(%esp), %ecx
mov 0x4(%esp), %eax
push %edx /* old_if, will be restored when switching back */
push %edi
push %esi
push %ebx
push %ebp
mov %eax, %ebp
mov %ecx, %ebx
call get_current
cmp %eax, %ebp
je .yield_to_spl_unlock_no_switch
push %esp
push %ebp
call save_and_setup_env
mov %eax, %esp
.yield_to_spl_unlock_no_switch:
xor %eax, %eax
mov %eax, (%ebx)
pop %ebp
pop %ebx
pop %esi
pop %edi
popf
ret
|