1 /* 2 * Copyright (c) 2014-2017, Siemens AG. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifndef EMBB_BASE_C_INTERNAL_ATOMIC_STORE_H_ 28 #define EMBB_BASE_C_INTERNAL_ATOMIC_STORE_H_ 29 30 #ifndef DOXYGEN 31 32 /* 33 * See file and_assign.h for a detailed (and operation independent) description 34 * of the following macro. 35 */ 36 #ifdef EMBB_PLATFORM_ARCH_X86 37 38 #ifdef EMBB_PLATFORM_COMPILER_MSVC 39 #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\ 40 extern void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)_asm( \ 41 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value); \ 42 EMBB_PLATFORM_INLINE void __fastcall EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\ 43 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) \ 44 { \ 45 _ReadWriteBarrier(); \ 46 EMBB_CAT2(embb_internal__atomic_store_, \ 47 EMBB_PARAMETER_SIZE_BYTE)_asm(pointer_to_value, new_value); \ 48 _ReadWriteBarrier(); \ 49 } 50 #elif defined(EMBB_PLATFORM_COMPILER_GNUC) 51 #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_X86_SIZE_SUFFIX)\ 52 EMBB_PLATFORM_INLINE void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* pointer_to_value, \ 53 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ 54 __asm__ __volatile__("lock xchg" EMBB_ATOMIC_X86_SIZE_SUFFIX " %1, %0" \ 55 : "+m" (*pointer_to_value), "+q" (new_value) \ 56 : \ 57 : "memory"); \ 58 } 59 #else 60 #error "No atomic fetch and store implementation found" 61 #endif 62 63 /* 64 * The three or four macro calls below generate the methods for 1, 2, 4, and 65 * bytes, as stated in the macro definition. 66 */ 67 EMBB_DEFINE_STORE(1, "b") 68 EMBB_DEFINE_STORE(2, "w") 69 EMBB_DEFINE_STORE(4, "l") 70 #ifdef EMBB_64_BIT_ATOMIC_AVAILABLE 71 EMBB_DEFINE_STORE(8, "q") 72 #endif 73 74 #elif defined(EMBB_PLATFORM_ARCH_ARM) 75 76 #if defined(EMBB_PLATFORM_COMPILER_GNUC) 77 #define EMBB_DEFINE_STORE(EMBB_PARAMETER_SIZE_BYTE, EMBB_ATOMIC_ARM_SIZE_SUFFIX)\ 78 EMBB_PLATFORM_INLINE \ 79 void EMBB_CAT2(embb_internal__atomic_store_, EMBB_PARAMETER_SIZE_BYTE)(\ 80 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_ATOMIC_, EMBB_PARAMETER_SIZE_BYTE) volatile* \ 81 pointer_to_value, \ 82 EMBB_CAT2(EMBB_BASE_BASIC_TYPE_SIZE_, EMBB_PARAMETER_SIZE_BYTE) new_value) {\ 83 __asm__ __volatile__( \ 84 "dmb\n\t" \ 85 "str" EMBB_ATOMIC_ARM_SIZE_SUFFIX " %1, [%0]" \ 86 : \ 87 : "r" (pointer_to_value), "r" (new_value) \ 88 : "memory"); \ 89 } 90 /* __sync_synchronize(); \ 91 *pointer_to_value = new_value; \ 92 __sync_synchronize(); \ 93 }*/ 94 #else 95 #error "No atomic fetch and store implementation found" 96 #endif 97 98 EMBB_DEFINE_STORE(1, "b") 99 EMBB_DEFINE_STORE(2, "h") 100 EMBB_DEFINE_STORE(4, "") 101 102 #else 103 #error "Unknown architecture" 104 #endif 105 106 #endif //DOXYGEN 107 108 #endif //EMBB_BASE_C_INTERNAL_ATOMIC_STORE_H_ 109