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