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
atomicAdd32bits(volatile uint32_t * val,uint32_t addend)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
atomicAddByte(volatile uint8_t * val,uint32_t addend)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
atomicXchgByte(volatile uint8_t * byte,uint32_t newVal)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
atomicXchg32bits(volatile uint32_t * word,uint32_t newVal)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
atomicCmpXchgByte(volatile uint8_t * byte,uint32_t prevVal,uint32_t newVal)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
atomicCmpXchg32bits(volatile uint32_t * word,uint32_t prevVal,uint32_t newVal)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