1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 
30 /* The purpose of this file is to export a small set of atomic-related
31  * functions from the C library, to ensure binary ABI compatibility for
32  * the NDK.
33  *
34  * These functions were initially exposed by the NDK through <sys/atomics.h>,
35  * which was unfortunate because their implementation didn't provide any
36  * memory barriers at all.
37  *
38  * This wasn't a problem for the platform code that used them, because it
39  * used explicit barrier instructions around them. On the other hand, it means
40  * that any NDK-generated machine code that linked against them would not
41  * perform correctly when running on multi-core devices.
42  *
43  * To fix this, the platform code was first modified to not use any of these
44  * functions (everything is now inlined through assembly statements, see
45  * libc/private/bionic_arm_inline.h and the headers it includes.
46  *
47  * The functions here are thus only for the benefit of NDK applications,
48  * and now includes full memory barriers to prevent any random memory ordering
49  * issue from cropping.
50  *
51  * Note that we also provide an updated <sys/atomics.h> header that defines
52  * always_inlined versions of the functions that use the GCC builtin
53  * intrinsics to perform the same thing.
54  *
55  * NOTE: There is no need for a similar file for non-ARM platforms.
56  */
57 
58 /* DO NOT INCLUDE <sys/atomics.h> HERE ! */
59 
60 int
__atomic_cmpxchg(int old,int _new,volatile int * ptr)61 __atomic_cmpxchg(int old, int _new, volatile int *ptr)
62 {
63     /* We must return 0 on success */
64     return __sync_val_compare_and_swap(ptr, old, _new) != old;
65 }
66 
67 int
__atomic_swap(int _new,volatile int * ptr)68 __atomic_swap(int _new, volatile int *ptr)
69 {
70     int prev;
71     do {
72         prev = *ptr;
73     } while (__sync_val_compare_and_swap(ptr, prev, _new) != prev);
74     return prev;
75 }
76 
77 int
__atomic_dec(volatile int * ptr)78 __atomic_dec(volatile int *ptr)
79 {
80   return __sync_fetch_and_sub (ptr, 1);
81 }
82 
83 int
__atomic_inc(volatile int * ptr)84 __atomic_inc(volatile int *ptr)
85 {
86   return __sync_fetch_and_add (ptr, 1);
87 }
88