1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <atomic.h> 18 19 uint32_t atomicAdd32bits(volatile uint32_t *val, uint32_t addend) 20 { 21 uint32_t old; 22 23 do { 24 old = *val; 25 } while (!atomicCmpXchg32bits(val, old, old + addend)); 26 27 return old; 28 } 29 30 uint32_t atomicAddByte(volatile uint8_t *val, uint32_t addend) 31 { 32 uint8_t old; 33 34 do { 35 old = *val; 36 } while (!atomicCmpXchgByte(val, old, old + addend)); 37 38 return old; 39 } 40 41 uint32_t atomicXchgByte(volatile uint8_t *byte, uint32_t newVal) 42 { 43 return __atomic_exchange_n(byte, newVal, __ATOMIC_ACQ_REL); 44 /* 45 uint32_t oldVal; 46 47 asm volatile( 48 " xchgb %1, %0 \n" 49 :"=r"(oldVal), "+m"(*byte) 50 :"0"(newVal) 51 :"memory" 52 ); 53 54 return oldVal; 55 */ 56 } 57 58 uint32_t atomicXchg32bits(volatile uint32_t *word, uint32_t newVal) 59 { 60 return __atomic_exchange_n(word, newVal, __ATOMIC_ACQ_REL); 61 /* 62 uint32_t oldVal; 63 64 asm volatile( 65 " xchgl %1, %0 \n" 66 :"=r"(oldVal), "+m"(*byte) 67 :"0"(newVal) 68 :"memory" 69 ); 70 71 return oldVal; 72 */ 73 } 74 75 bool atomicCmpXchgByte(volatile uint8_t *byte, uint32_t prevVal, uint32_t newVal) 76 { 77 return __sync_bool_compare_and_swap (byte, prevVal, newVal); 78 /* 79 uint32_t ret; 80 81 asm volatile( 82 " lock cmpxchgb %2, %1 \n" 83 :"=a"(ret), "+m"(*byte) 84 :"r"(newVal), "0"(prevVal) 85 :"cc", "memory" 86 ); 87 88 return ret == prevVal; 89 */ 90 } 91 92 bool atomicCmpXchg32bits(volatile uint32_t *word, uint32_t prevVal, uint32_t newVal) 93 { 94 return __sync_bool_compare_and_swap (word, prevVal, newVal); 95 /* 96 uint32_t ret; 97 98 asm volatile( 99 " lock cmpxchgl %2, %1 \n" 100 :"=a"(ret), "+m"(*word) 101 :"r"(newVal), "0"(prevVal) 102 :"cc", "memory" 103 ); 104 105 return ret == prevVal; 106 */ 107 } 108