Home | History | Annotate | Download | only in x86
      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