10fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner/* 20fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * Copyright (C) 2011 The Android Open Source Project 30fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * All rights reserved. 40fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 50fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * Redistribution and use in source and binary forms, with or without 60fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * modification, are permitted provided that the following conditions 70fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * are met: 80fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * * Redistributions of source code must retain the above copyright 90fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * notice, this list of conditions and the following disclaimer. 100fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * * Redistributions in binary form must reproduce the above copyright 110fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * notice, this list of conditions and the following disclaimer in 120fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * the documentation and/or other materials provided with the 130fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * distribution. 140fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 150fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 160fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 170fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 180fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 190fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 200fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 210fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 220fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 230fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 240fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 250fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * SUCH DAMAGE. 270fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner */ 280fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 290fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 300fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner/* The purpose of this file is to export a small set of atomic-related 310fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * functions from the C library, to ensure binary ABI compatibility for 320fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * the NDK. 330fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 340fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * These functions were initially exposed by the NDK through <sys/atomics.h>, 350fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * which was unfortunate because their implementation didn't provide any 360fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * memory barriers at all. 370fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 380fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * This wasn't a problem for the platform code that used them, because it 390fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * used explicit barrier instructions around them. On the other hand, it means 400fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * that any NDK-generated machine code that linked against them would not 410fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * perform correctly when running on multi-core devices. 420fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 430fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * To fix this, the platform code was first modified to not use any of these 440fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * functions (everything is now inlined through assembly statements, see 450fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * libc/private/bionic_arm_inline.h and the headers it includes. 460fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 470fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * The functions here are thus only for the benefit of NDK applications, 480fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * and now includes full memory barriers to prevent any random memory ordering 490fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * issue from cropping. 500fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 510fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * Note that we also provide an updated <sys/atomics.h> header that defines 520fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * always_inlined versions of the functions that use the GCC builtin 530fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * intrinsics to perform the same thing. 540fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * 550fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner * NOTE: There is no need for a similar file for non-ARM platforms. 560fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner */ 570fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 580fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner/* DO NOT INCLUDE <sys/atomics.h> HERE ! */ 590fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 600fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turnerint 61f1a39dce60be0b453416e1b82a6d445a7677eb4bDavid 'Digit' Turner__atomic_cmpxchg(int old, int _new, volatile int *ptr) 620fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner{ 630fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner /* We must return 0 on success */ 640fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner return __sync_val_compare_and_swap(ptr, old, _new) != old; 650fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner} 660fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 670fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turnerint 680fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner__atomic_swap(int _new, volatile int *ptr) 690fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner{ 700fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner int prev; 710fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner do { 720fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner prev = *ptr; 730fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner } while (__sync_val_compare_and_swap(ptr, prev, _new) != prev); 740fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner return prev; 750fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner} 760fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 770fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turnerint 780fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner__atomic_dec(volatile int *ptr) 790fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner{ 800fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner return __sync_fetch_and_sub (ptr, 1); 810fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner} 820fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner 830fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turnerint 840fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner__atomic_inc(volatile int *ptr) 850fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner{ 860fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner return __sync_fetch_and_add (ptr, 1); 870fec6b9d88ee5a9e359b2208038f9806c0804538David 'Digit' Turner} 88