1f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* 2f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * Copyright (C) 2011 The Android Open Source Project 3f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * 4f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * Licensed under the Apache License, Version 2.0 (the "License"); 5f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * you may not use this file except in compliance with the License. 6f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * You may obtain a copy of the License at 7f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * 8f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * http://www.apache.org/licenses/LICENSE-2.0 9f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * 10f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * Unless required by applicable law or agreed to in writing, software 11f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * distributed under the License is distributed on an "AS IS" BASIS, 12f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * See the License for the specific language governing permissions and 14f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * limitations under the License. 15f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham */ 16f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#ifndef BIONIC_ATOMIC_MIPS_H 17f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#define BIONIC_ATOMIC_MIPS_H 18f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 19f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* Define a full memory barrier, this is only needed if we build the 20f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * platform for a multi-core device. 21f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham */ 22f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#if defined(ANDROID_SMP) && ANDROID_SMP == 1 23f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ void 24f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_memory_barrier() 25f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 26f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ( "sync" : : : "memory" ); 27f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 28f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#else 29f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ void 30f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_memory_barrier() 31f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 32f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham /* A simple compiler barrier */ 33f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ( "" : : : "memory" ); 34f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 35f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#endif 36f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 37f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* Compare-and-swap, without any explicit barriers. Note that this function 38f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * returns 0 on success, and 1 on failure. The opposite convention is typically 39f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham * used on other platforms. 40f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham */ 41f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ int 42f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_cmpxchg(int32_t old_value, int32_t new_value, volatile int32_t* ptr) 43f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 44f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham int32_t prev, status; 45f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ("1: move %[status], %[new_value] \n" 46f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " ll %[prev], 0(%[ptr]) \n" 47f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " bne %[old_value], %[prev], 2f \n" 48f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " sc %[status], 0(%[ptr]) \n" 49f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " beqz %[status], 1b \n" 50f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham "2: \n" 51f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [prev]"=&r"(prev), [status]"=&r"(status), "+m"(*ptr) 52f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [new_value]"r"(new_value), [old_value]"r"(old_value), [ptr]"r"(ptr) 53f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : "memory"); 54f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham return prev != old_value; 55f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 56f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 57f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 58f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* Swap, without any explicit barriers */ 59f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ int32_t 60f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_swap(int32_t new_value, volatile int32_t *ptr) 61f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 62f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham int32_t prev, status; 63f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ("1: move %[status], %[new_value] \n" 64f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " ll %[prev], 0(%[ptr]) \n" 65f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " sc %[status], 0(%[ptr]) \n" 66f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " beqz %[status], 1b \n" 67f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [prev]"=&r"(prev), [status]"=&r"(status), "+m"(*ptr) 68f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [ptr]"r"(ptr), [new_value]"r"(new_value) 69f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : "memory"); 70f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham return prev; 71f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 72f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 73f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* Atomic increment, without explicit barriers */ 74f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ int32_t 75f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_atomic_inc(volatile int32_t *ptr) 76f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 77f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham int32_t prev, status; 78f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ("1: ll %[prev], 0(%[ptr]) \n" 79f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " addiu %[status], %[prev], 1 \n" 80f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " sc %[status], 0(%[ptr]) \n" 81f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " beqz %[status], 1b \n" 82f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [prev]"=&r" (prev), [status]"=&r"(status), "+m" (*ptr) 83f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [ptr]"r"(ptr) 84f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : "memory"); 85f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham return prev; 86f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 87f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham 88f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham/* Atomic decrement, without explicit barriers */ 89f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__ATOMIC_INLINE__ int32_t 90f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham__bionic_atomic_dec(volatile int32_t *ptr) 91f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham{ 92f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham int32_t prev, status; 93f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham __asm__ __volatile__ ("1: ll %[prev], 0(%[ptr]) \n" 94f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " addiu %[status], %[prev], -1 \n" 95f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " sc %[status], 0(%[ptr]) \n" 96f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham " beqz %[status], 1b \n" 97f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [prev]"=&r" (prev), [status]"=&r"(status), "+m" (*ptr) 98f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : [ptr]"r"(ptr) 99f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham : "memory"); 100f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham return prev; 101f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham} 102f7fb9e1ef1e159be2fded066d126d8e1f111b772Raghu Gandham#endif /* BIONIC_ATOMIC_MIPS_H */ 103