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 225206d5971208fab8208669dabc98bbb9f7e4a45aBen Cheng#ifndef ANDROID_ATOMIC_INLINE 235206d5971208fab8208669dabc98bbb9f7e4a45aBen Cheng#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline)) 245206d5971208fab8208669dabc98bbb9f7e4a45aBen Cheng#endif 255206d5971208fab8208669dabc98bbb9f7e4a45aBen Cheng 2662980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE void android_compiler_barrier() 2793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 2893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("" : : : "memory"); 2993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 3093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 3162980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE void android_memory_barrier() 32464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 3362980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#if ANDROID_SMP == 0 34464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom android_compiler_barrier(); 3562980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#else 3693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("dmb" : : : "memory"); 3762980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#endif 3893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 3962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers 4062980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE void android_memory_store_barrier() 41464431e65fbede57b0d41d230fe6f6dc465c20f8Brian Carlstrom{ 4262980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#if ANDROID_SMP == 0 4362980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers android_compiler_barrier(); 4493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#else 4562980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers __asm__ __volatile__ ("dmb st" : : : "memory"); 4693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif 4762980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers} 4893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 495206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengextern ANDROID_ATOMIC_INLINE 505206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengint32_t android_atomic_acquire_load(volatile const int32_t *ptr) 5193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 5293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t value = *ptr; 5393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 5493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return value; 5593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 5693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 575206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengextern ANDROID_ATOMIC_INLINE 585206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengint32_t android_atomic_release_load(volatile const int32_t *ptr) 5993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 6093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 6193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return *ptr; 6293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 6393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 6462980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 6562980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersvoid android_atomic_acquire_store(int32_t value, volatile int32_t *ptr) 6693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 6793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 6893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 6993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 7162980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 7262980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersvoid android_atomic_release_store(int32_t value, volatile int32_t *ptr) 7393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 7493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 7593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro *ptr = value; 7693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 7793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 7862980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 7962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint android_atomic_cas(int32_t old_value, int32_t new_value, 8062980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers volatile int32_t *ptr) 8193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 8293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, status; 8393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 8493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%3]\n" 8593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "mov %1, #0\n" 8693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "teq %0, %4\n" 8762980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#ifdef __thumb2__ 8862980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers "it eq\n" 8962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers#endif 9093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strexeq %1, %5, [%3]" 9193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (status), "+m"(*ptr) 9293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (old_value), "r" (new_value) 9393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 9493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 9593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev != old_value; 9693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 9793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 9862980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 9962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint android_atomic_acquire_cas(int32_t old_value, int32_t new_value, 10062980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers volatile int32_t *ptr) 10193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 10293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int status = android_atomic_cas(old_value, new_value, ptr); 10393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 10493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return status; 10593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 10693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 10762980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 10862980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint android_atomic_release_cas(int32_t old_value, int32_t new_value, 10962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogers volatile int32_t *ptr) 11093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 11193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 11293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_cas(old_value, new_value, ptr); 11393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 11493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 11562980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 11662980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint32_t android_atomic_add(int32_t increment, volatile int32_t *ptr) 11793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 11893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 11993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 12093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 12193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 12293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "add %1, %0, %5\n" 12393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 12493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 12593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 12693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (increment) 12793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 12893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 12993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 13093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 13193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 1325206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengextern ANDROID_ATOMIC_INLINE int32_t android_atomic_inc(volatile int32_t *addr) 133d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 13493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(1, addr); 13593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 13693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 1375206d5971208fab8208669dabc98bbb9f7e4a45aBen Chengextern ANDROID_ATOMIC_INLINE int32_t android_atomic_dec(volatile int32_t *addr) 138d55f0adfb5ec4202ad5bd5d188e66c0f6a27b0aaCarl Shapiro{ 13993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return android_atomic_add(-1, addr); 14093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 14193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 14262980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 14362980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint32_t android_atomic_and(int32_t value, volatile int32_t *ptr) 14493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 14593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 14693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 14793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 14893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 14993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "and %1, %0, %5\n" 15093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 15193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 15293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 15393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 15493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 15593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 15693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 15793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 15893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 15962980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersextern ANDROID_ATOMIC_INLINE 16062980e817c51c56208971ed5c3e98e0cb21e1685Ian Rogersint32_t android_atomic_or(int32_t value, volatile int32_t *ptr) 16193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro{ 16293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro int32_t prev, tmp, status; 16393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro android_memory_barrier(); 16493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro do { 16593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro __asm__ __volatile__ ("ldrex %0, [%4]\n" 16693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "orr %1, %0, %5\n" 16793b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "strex %2, %1, [%4]" 16893b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "=&r" (prev), "=&r" (tmp), 16993b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro "=&r" (status), "+m" (*ptr) 17093b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "r" (ptr), "Ir" (value) 17193b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro : "cc"); 17293b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro } while (__builtin_expect(status != 0, 0)); 17393b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro return prev; 17493b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro} 17593b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro 17693b0cb40c18cae594c931677be2b9214420610b7Carl Shapiro#endif /* ANDROID_CUTILS_ATOMIC_ARM_H */ 177