blob: 666e1821ce92a7019446021d2b1b0acb077d6fc7 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001#include <sys/linux-syscalls.h>
2
3#define FUTEX_WAIT 0
4#define FUTEX_WAKE 1
5
6
7/*
8 * int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout)
9 */
10.text
11.globl __futex_wait
12.type __futex_wait, @function
13.align 4
14__futex_wait:
15 pushl %ebx
16 pushl %esi
17 mov 12(%esp), %ebx /* ftx */
18 movl $FUTEX_WAIT, %ecx
19 mov 16(%esp), %edx /* val */
20 mov 20(%esp), %esi /* timeout */
21 movl $__NR_futex, %eax
22 int $0x80
23 popl %esi
24 popl %ebx
25 ret
26
27
28/* int __futex_wake(volatile void *ftx, int count) */
29
30.text
31.globl __futex_wake
32.type __futex_wake, @function
33.align 4
34__futex_wake:
35 pushl %ebx
36 mov 8(%esp), %ebx /* ftx */
37 movl $FUTEX_WAKE, %ecx
38 mov 12(%esp), %edx /* count */
39 movl $__NR_futex, %eax
40 int $0x80
41 popl %ebx
42 ret
43
David 'Digit' Turner88f06cd2010-03-18 17:13:41 -070044/* int __futex_syscall3(volatile void *ftx, int op, int count) */
45.text
46.globl __futex_syscall3
47.type __futex_syscall3, @function
48.align 4
49__futex_syscall3:
50 pushl %ebx
51 movl 8(%esp), %ebx /* ftx */
52 movl 12(%esp), %ecx /* op */
53 movl 16(%esp), %edx /* value */
54 movl $__NR_futex, %eax
55 int $0x80
56 popl %ebx
57 ret
58
59/* int __futex_syscall4(volatile void *ftx, int op, int val, const struct timespec *timeout) */
60.text
61.globl __futex_syscall4
62.type __futex_syscall4, @function
63.align 4
64__futex_syscall4:
65 pushl %ebx
66 pushl %esi
67 movl 12(%esp), %ebx /* ftx */
68 movl 16(%esp), %ecx /* op */
69 movl 20(%esp), %edx /* val */
70 movl 24(%esp), %esi /* timeout */
71 movl $__NR_futex, %eax
72 int $0x80
73 popl %esi
74 popl %ebx
75 ret
The Android Open Source Project1dc9e472009-03-03 19:28:35 -080076
77/* int __atomic_cmpxchg(int old, int new, volatile int* addr) */
78
79.text
80.globl __atomic_cmpxchg
81.type __atomic_cmpxchg, @function
82.align 4
83__atomic_cmpxchg:
84 mov 4(%esp), %eax /* old */
85 mov 8(%esp), %ecx /* new */
86 mov 12(%esp), %edx /* addr */
87 lock cmpxchg %ecx, (%edx)
88 jnz 1f
89 xor %eax, %eax
90 jmp 2f
911:
92 movl $1, %eax
932:
94 ret /* 0 == success, 1 == failure */
95
96
97/* int __atomic_swap(int new, volatile int* addr) */
98
99.text
100.globl __atomic_swap
101.type __atomic_swap, @function
102.align 4
103__atomic_swap:
104 mov 4(%esp), %ecx /* new */
105 mov 8(%esp), %edx /* addr */
106 lock xchg %ecx, (%edx)
107 mov %ecx, %eax
108 ret
109
110
111/*
112 * int __atomic_dec(volatile int* addr)
113 *
114 * My x86 asm is really rusty.. this is probably suboptimal
115 */
116
117.text
118.globl __atomic_dec
119.type __atomic_dec, @function
120.align 4
121__atomic_dec:
122 pushl %ebx
123 pushl %esi
124 movl 12(%esp), %ebx /* addr */
125
1261:
127 movl (%ebx), %esi /* old = *addr */
128 movl %esi, %edx
129 subl $1, %edx /* new = old - 1 */
130
131 pushl %ebx
132 pushl %edx
133 pushl %esi
134 call __atomic_cmpxchg
135 addl $12, %esp
136 test %eax, %eax
137 jnz 1b
138
139 movl %esi, %eax /* return old */
140 popl %esi
141 popl %ebx
142 ret
143
144
145.text
146/* int __atomic_inc(volatile int* addr) */
147.globl __atomic_inc
148.type __atomic_inc, @function
149.align 4
150__atomic_inc:
151 pushl %ebx
152 pushl %esi
153 movl 12(%esp), %ebx /* addr */
154
1551:
156 movl (%ebx), %esi /* old = *addr */
157 movl %esi, %edx
158 addl $1, %edx /* new = old + 1 */
159
160 pushl %ebx
161 pushl %edx
162 pushl %esi
163 call __atomic_cmpxchg
164 addl $12, %esp
165 test %eax, %eax
166 jnz 1b
167
168 movl %esi, %eax /* return old */
169 popl %esi
170 popl %ebx
171 ret
172