atomic-arm.h revision d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aa
193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro/* 293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * Copyright (C) 2010 The Android Open Source Project 393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * 493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * Licensed under the Apache License, Version 2.0 (the "License"); 593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * you may not use this file except in compliance with the License. 693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * You may obtain a copy of the License at 793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * 893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * http://www.apache.org/licenses/LICENSE-2.0 993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * 1093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * Unless required by applicable law or agreed to in writing, software 1193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * distributed under the License is distributed on an "AS IS" BASIS, 1293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * See the License for the specific language governing permissions and 1493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro * limitations under the License. 1593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro */ 1693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 1793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#ifndef ANDROID_CUTILS_ATOMIC_ARM_H 1893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#define ANDROID_CUTILS_ATOMIC_ARM_H 1993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 2093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#include <stdint.h> 2193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#include <machine/cpu-features.h> 2293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 2393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_compiler_barrier(void) 2493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 2593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("" : : : "memory"); 2693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 2793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 2893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if ANDROID_SMP == 0 2993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 3093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 3193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_compiler_barrier(); 3293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 3393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_DMB) 3493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 3593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 3693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("dmb" : : : "memory"); 3793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 3893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 3993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 4093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 4193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" 4293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : : "r" (0) : "memory"); 4393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 4493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 4593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 4693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 4793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro typedef void (kuser_memory_barrier)(void); 4893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro (*(kuser_memory_barrier *)0xffff0fa0)(); 4993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 5093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 5193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 52d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr) 5393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 5493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t value = *ptr; 5593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 5693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return value; 5793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 5893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 59d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_release_load(volatile const int32_t *ptr) 6093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 6193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 6293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return *ptr; 6393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 6493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 6593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_atomic_acquire_store(int32_t value, 6693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 6793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 6893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 6993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 7093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 7293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_atomic_release_store(int32_t value, 7393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 7493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 7593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 7693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 7793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 7993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 8093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int android_atomic_cas(int32_t old_value, int32_t new_value, 8193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr); 8293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 8393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_cas(int32_t old_value, int32_t new_value, 8493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 8593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 8693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 8793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 8893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%3]\n" 8993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "mov %1, #0\n" 9093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "teq %0, %4\n" 9193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strexeq %1, %5, [%3]" 9293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (status), "+m"(*ptr) 9393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (old_value), "r" (new_value) 9493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 9593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 9693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev != old_value; 9793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 9893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 9993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_cas(int32_t old_value, int32_t new_value, 10093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 10193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 10293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro typedef int (kuser_cmpxchg)(int32_t, int32_t, volatile int32_t *); 10393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 10493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 10593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 10693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = (*(kuser_cmpxchg *)0xffff0fc0)(old_value, new_value, ptr); 10793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro if (__builtin_expect(status == 0, 1)) 10893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return 0; 10993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 11093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (prev == old_value); 11193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return 1; 11293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 11393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 11493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 11593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_acquire_cas(int32_t old_value, 11693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t new_value, 11793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 11893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 11993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int status = android_atomic_cas(old_value, new_value, ptr); 12093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 12193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return status; 12293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 12393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 12493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_release_cas(int32_t old_value, 12593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t new_value, 12693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 12793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 12893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 12993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_cas(old_value, new_value, ptr); 13093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 13193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 13293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 13393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 13493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_swap(int32_t new_value, 13593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr); 13693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 13793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_swap(int32_t new_value, 13893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 13993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 14093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 14193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 14293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%3]\n" 14393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %1, %4, [%3]" 14493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (status), "+m" (*ptr) 14593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "r" (new_value) 14693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 14793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 14893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 14993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 15093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 15193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 15293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_swap(int32_t new_value, 15393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 15493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 15593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev; 15693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("swp %0, %2, [%3]" 15793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "+m" (*ptr) 15893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (new_value), "r" (ptr) 15993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 16093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 16193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 16293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 16393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 16493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 16593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 16693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_add(int32_t increment, 16793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr); 16893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 16993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_add(int32_t increment, 17093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 17193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 17293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 17393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 17493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 17593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 17693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "add %1, %0, %5\n" 17793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 17893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 17993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 18093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (increment) 18193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 18293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 18393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 18493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 18593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 18693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_add(int32_t increment, 18793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 18893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 18993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 19093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 19193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 19293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 19393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev + increment, ptr); 19493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 19593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 19693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 19793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 19893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 199d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_inc(volatile int32_t *addr) 200d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 20193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(1, addr); 20293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 20393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 204d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_dec(volatile int32_t *addr) 205d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 20693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(-1, addr); 20793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 20893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 20993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 21093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_and(int32_t value, volatile int32_t *ptr); 21193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 21293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr) 21393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 21493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 21593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 21693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 21793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 21893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "and %1, %0, %5\n" 21993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 22093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 22193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 22293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 22393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 22493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 22593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 22693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 22793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 22893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr) 22993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 23093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 23193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 23293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 23393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 23493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev & value, ptr); 23593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 23693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 23793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 23893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 23993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 24093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 24193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_or(int32_t value, volatile int32_t *ptr); 24293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 24393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr) 24493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 24593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 24693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 24793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 24893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 24993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "orr %1, %0, %5\n" 25093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 25193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 25293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 25393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 25493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 25593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 25693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 25793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 25893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 25993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr) 26093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 26193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 26293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 26393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 26493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 26593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev | value, ptr); 26693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 26793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 26893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 26993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 27093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 27193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif /* ANDROID_CUTILS_ATOMIC_ARM_H */ 272