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{ 31464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom android_compiler_barrier(); 32464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom} 33464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstromextern inline void android_memory_store_barrier(void) 34464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 35464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom android_compiler_barrier(); 3693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 3793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_DMB) 3893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 3993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 4093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("dmb" : : : "memory"); 4193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 42464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstromextern inline void android_memory_store_barrier(void) 43464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 442bf937e6bbe3137cd97596e8f1f26ed45415eb4bAndy McFadden __asm__ __volatile__ ("dmb st" : : : "memory"); 45464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom} 4693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 4793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 4893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 49464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); 50464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom} 51464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstromextern inline void android_memory_store_barrier(void) 52464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 53464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom android_memory_barrier(); 5493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 5593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 5693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_memory_barrier(void) 5793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 5893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro typedef void (kuser_memory_barrier)(void); 5993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro (*(kuser_memory_barrier *)0xffff0fa0)(); 6093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 61464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstromextern inline void android_memory_store_barrier(void) 62464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 63464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom android_memory_barrier(); 64464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom} 6593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 6693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 67d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_acquire_load(volatile const int32_t *ptr) 6893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 6993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t value = *ptr; 7093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 7193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return value; 7293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 74d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_release_load(volatile const int32_t *ptr) 7593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 7693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 7793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return *ptr; 7893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 8093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_atomic_acquire_store(int32_t value, 8193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 8293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 8393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 8493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 8593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 8693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 8793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline void android_atomic_release_store(int32_t value, 8893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 8993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 9093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 9193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 9293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 9393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 9493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 9593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int android_atomic_cas(int32_t old_value, int32_t new_value, 9693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr); 9793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 9893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_cas(int32_t old_value, int32_t new_value, 9993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 10093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 10193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 10293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 10393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%3]\n" 10493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "mov %1, #0\n" 10593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "teq %0, %4\n" 10693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strexeq %1, %5, [%3]" 10793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (status), "+m"(*ptr) 10893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (old_value), "r" (new_value) 10993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 11093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 11193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev != old_value; 11293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 11393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 11493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_cas(int32_t old_value, int32_t new_value, 11593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 11693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 11793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro typedef int (kuser_cmpxchg)(int32_t, int32_t, volatile int32_t *); 11893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 11993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 12093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 12193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = (*(kuser_cmpxchg *)0xffff0fc0)(old_value, new_value, ptr); 12293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro if (__builtin_expect(status == 0, 1)) 12393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return 0; 12493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 12593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (prev == old_value); 12693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return 1; 12793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 12893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 12993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 13093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_acquire_cas(int32_t old_value, 13193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t new_value, 13293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 13393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 13493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int status = android_atomic_cas(old_value, new_value, ptr); 13593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 13693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return status; 13793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 13893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 13993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int android_atomic_release_cas(int32_t old_value, 14093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t new_value, 14193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 14293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 14393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 14493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_cas(old_value, new_value, ptr); 14593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 14693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 14793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 14893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 14993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_add(int32_t increment, 15093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr); 15193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 15293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_add(int32_t increment, 15393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 15493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 15593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 15693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 15793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 15893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 15993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "add %1, %0, %5\n" 16093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 16193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 16293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 16393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (increment) 16493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 16593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 16693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 16793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 16893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 16993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_add(int32_t increment, 17093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro volatile int32_t *ptr) 17193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 17293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 17393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 17493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 17593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 17693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev + increment, ptr); 17793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 17893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 17993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 18093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 18193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 182d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_inc(volatile int32_t *addr) 183d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 18493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(1, addr); 18593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 18693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 187d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiroextern inline int32_t android_atomic_dec(volatile int32_t *addr) 188d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 18993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(-1, addr); 19093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 19193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 19293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 19393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_and(int32_t value, volatile int32_t *ptr); 19493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 19593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr) 19693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 19793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 19893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 19993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 20093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 20193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "and %1, %0, %5\n" 20293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 20393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 20493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 20593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 20693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 20793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 20893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 20993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 21093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 21193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_and(int32_t value, volatile int32_t *ptr) 21293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 21393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 21493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 21593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 21693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 21793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev & value, ptr); 21893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 21993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 22093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 22193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 22293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 22393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#if defined(__thumb__) 22493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern int32_t android_atomic_or(int32_t value, volatile int32_t *ptr); 22593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#elif defined(__ARM_HAVE_LDREX_STREX) 22693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr) 22793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 22893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 22993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 23093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 23193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 23293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "orr %1, %0, %5\n" 23393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 23493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 23593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 23693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 23793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 23893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 23993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 24093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 24193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 24293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiroextern inline int32_t android_atomic_or(int32_t value, volatile int32_t *ptr) 24393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 24493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 24593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 24693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 24793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro prev = *ptr; 24893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro status = android_atomic_cas(prev, prev | value, ptr); 24993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 25093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 25193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 25293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 25393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 25493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif /* ANDROID_CUTILS_ATOMIC_ARM_H */ 255