diff options
-rw-r--r-- | libc/arch-x86/bionic/atomics_x86.S | 97 | ||||
-rw-r--r-- | libc/arch-x86/include/sys/atomics.h | 65 |
2 files changed, 65 insertions, 97 deletions
diff --git a/libc/arch-x86/bionic/atomics_x86.S b/libc/arch-x86/bionic/atomics_x86.S index 666e1821c..e98a391ee 100644 --- a/libc/arch-x86/bionic/atomics_x86.S +++ b/libc/arch-x86/bionic/atomics_x86.S @@ -73,100 +73,3 @@ __futex_syscall4: popl %esi popl %ebx ret - -/* int __atomic_cmpxchg(int old, int new, volatile int* addr) */ - -.text -.globl __atomic_cmpxchg -.type __atomic_cmpxchg, @function -.align 4 -__atomic_cmpxchg: - mov 4(%esp), %eax /* old */ - mov 8(%esp), %ecx /* new */ - mov 12(%esp), %edx /* addr */ - lock cmpxchg %ecx, (%edx) - jnz 1f - xor %eax, %eax - jmp 2f -1: - movl $1, %eax -2: - ret /* 0 == success, 1 == failure */ - - -/* int __atomic_swap(int new, volatile int* addr) */ - -.text -.globl __atomic_swap -.type __atomic_swap, @function -.align 4 -__atomic_swap: - mov 4(%esp), %ecx /* new */ - mov 8(%esp), %edx /* addr */ - lock xchg %ecx, (%edx) - mov %ecx, %eax - ret - - -/* - * int __atomic_dec(volatile int* addr) - * - * My x86 asm is really rusty.. this is probably suboptimal - */ - -.text -.globl __atomic_dec -.type __atomic_dec, @function -.align 4 -__atomic_dec: - pushl %ebx - pushl %esi - movl 12(%esp), %ebx /* addr */ - -1: - movl (%ebx), %esi /* old = *addr */ - movl %esi, %edx - subl $1, %edx /* new = old - 1 */ - - pushl %ebx - pushl %edx - pushl %esi - call __atomic_cmpxchg - addl $12, %esp - test %eax, %eax - jnz 1b - - movl %esi, %eax /* return old */ - popl %esi - popl %ebx - ret - - -.text -/* int __atomic_inc(volatile int* addr) */ -.globl __atomic_inc -.type __atomic_inc, @function -.align 4 -__atomic_inc: - pushl %ebx - pushl %esi - movl 12(%esp), %ebx /* addr */ - -1: - movl (%ebx), %esi /* old = *addr */ - movl %esi, %edx - addl $1, %edx /* new = old + 1 */ - - pushl %ebx - pushl %edx - pushl %esi - call __atomic_cmpxchg - addl $12, %esp - test %eax, %eax - jnz 1b - - movl %esi, %eax /* return old */ - popl %esi - popl %ebx - ret - diff --git a/libc/arch-x86/include/sys/atomics.h b/libc/arch-x86/include/sys/atomics.h new file mode 100644 index 000000000..7aed3ae0b --- /dev/null +++ b/libc/arch-x86/include/sys/atomics.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef _SYS_ATOMICS_H +#define _SYS_ATOMICS_H + +#include <sys/cdefs.h> +#include <sys/time.h> + +__BEGIN_DECLS + +static inline __attribute__((always_inline)) int +__atomic_cmpxchg(int old, int _new, volatile int *ptr) +{ + return !__sync_bool_compare_and_swap (ptr, old, _new); +} + +static inline __attribute__((always_inline)) int +__atomic_swap(int _new, volatile int *ptr) +{ + return __sync_lock_test_and_set(ptr, _new); +} + +static inline __attribute__((always_inline)) int +__atomic_dec(volatile int *ptr) +{ + return __sync_fetch_and_sub (ptr, 1); +} + +static inline __attribute__((always_inline)) int +__atomic_inc(volatile int *ptr) +{ + return __sync_fetch_and_add (ptr, 1); +} + +int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout); +int __futex_wake(volatile void *ftx, int count); + +__END_DECLS + +#endif /* _SYS_ATOMICS_H */ |