Andrew Geissler | 9aee500 | 2022-03-30 16:27:02 +0000 | [diff] [blame] | 1 | Prevent Clang from emitting atomic libcalls |
| 2 | |
| 3 | Clang expects 8-byte alignment for some 64-bit atomic operations |
| 4 | in some 32-bit targets. Native instruction lock cmpxchg8b (for x86) |
| 5 | should only require 4-byte alignment. |
| 6 | |
| 7 | This patch tries to add 8-byte alignents to data needing atomic ops |
| 8 | which helps clang to not generate the libatomic calls but emit |
| 9 | builtins directly. |
| 10 | |
| 11 | Upstream-Status: Submitted[https://jira.mariadb.org/browse/MDEV-28162] |
| 12 | Signed-off-by: Khem Raj <raj.khem@gmail.com> |
| 13 | |
| 14 | --- a/include/my_atomic.h |
| 15 | +++ b/include/my_atomic.h |
| 16 | @@ -115,6 +115,16 @@ |
| 17 | #include "atomic/gcc_builtins.h" |
| 18 | #endif |
| 19 | |
| 20 | +#include <stdint.h> |
| 21 | + |
| 22 | +# ifdef __GNUC__ |
| 23 | +typedef __attribute__((__aligned__(8))) int64 ATOMIC_I64; |
| 24 | +typedef __attribute__((__aligned__(8))) uint64 ATOMIC_U64; |
| 25 | +# else |
| 26 | +typedef int64 ATOMIC_I64; |
| 27 | +typedef uint64 ATOMIC_U64; |
| 28 | +# endif |
| 29 | + |
| 30 | #if SIZEOF_LONG == 4 |
| 31 | #define my_atomic_addlong(A,B) my_atomic_add32((int32*) (A), (B)) |
| 32 | #define my_atomic_loadlong(A) my_atomic_load32((int32*) (A)) |
| 33 | @@ -123,12 +133,12 @@ |
| 34 | #define my_atomic_faslong(A,B) my_atomic_fas32((int32*) (A), (B)) |
| 35 | #define my_atomic_caslong(A,B,C) my_atomic_cas32((int32*) (A), (int32*) (B), (C)) |
| 36 | #else |
| 37 | -#define my_atomic_addlong(A,B) my_atomic_add64((int64*) (A), (B)) |
| 38 | -#define my_atomic_loadlong(A) my_atomic_load64((int64*) (A)) |
| 39 | -#define my_atomic_loadlong_explicit(A,O) my_atomic_load64_explicit((int64*) (A), (O)) |
| 40 | -#define my_atomic_storelong(A,B) my_atomic_store64((int64*) (A), (B)) |
| 41 | -#define my_atomic_faslong(A,B) my_atomic_fas64((int64*) (A), (B)) |
| 42 | -#define my_atomic_caslong(A,B,C) my_atomic_cas64((int64*) (A), (int64*) (B), (C)) |
| 43 | +#define my_atomic_addlong(A,B) my_atomic_add64((ATOMIC_I64*) (A), (B)) |
| 44 | +#define my_atomic_loadlong(A) my_atomic_load64((ATOMIC_I64*) (A)) |
| 45 | +#define my_atomic_loadlong_explicit(A,O) my_atomic_load64_explicit((ATOMIC_I64*) (A), (O)) |
| 46 | +#define my_atomic_storelong(A,B) my_atomic_store64((ATOMIC_I64*) (A), (B)) |
| 47 | +#define my_atomic_faslong(A,B) my_atomic_fas64((ATOMIC_I64*) (A), (B)) |
| 48 | +#define my_atomic_caslong(A,B,C) my_atomic_cas64((ATOMIC_I64*) (A), (ATOMIC_I64*) (B), (C)) |
| 49 | #endif |
| 50 | |
| 51 | #ifndef MY_MEMORY_ORDER_SEQ_CST |
| 52 | --- a/storage/perfschema/pfs_atomic.h |
| 53 | +++ b/storage/perfschema/pfs_atomic.h |
| 54 | @@ -41,7 +41,7 @@ public: |
| 55 | } |
| 56 | |
| 57 | /** Atomic load. */ |
| 58 | - static inline int64 load_64(int64 *ptr) |
| 59 | + static inline int64 load_64(ATOMIC_I64 *ptr) |
| 60 | { |
| 61 | return my_atomic_load64(ptr); |
| 62 | } |
| 63 | @@ -53,9 +53,9 @@ public: |
| 64 | } |
| 65 | |
| 66 | /** Atomic load. */ |
| 67 | - static inline uint64 load_u64(uint64 *ptr) |
| 68 | + static inline uint64 load_u64(ATOMIC_U64 *ptr) |
| 69 | { |
| 70 | - return (uint64) my_atomic_load64((int64*) ptr); |
| 71 | + return (uint64) my_atomic_load64((ATOMIC_I64*) ptr); |
| 72 | } |
| 73 | |
| 74 | /** Atomic store. */ |
| 75 | @@ -65,7 +65,7 @@ public: |
| 76 | } |
| 77 | |
| 78 | /** Atomic store. */ |
| 79 | - static inline void store_64(int64 *ptr, int64 value) |
| 80 | + static inline void store_64(ATOMIC_I64 *ptr, int64 value) |
| 81 | { |
| 82 | my_atomic_store64(ptr, value); |
| 83 | } |
| 84 | @@ -77,9 +77,9 @@ public: |
| 85 | } |
| 86 | |
| 87 | /** Atomic store. */ |
| 88 | - static inline void store_u64(uint64 *ptr, uint64 value) |
| 89 | + static inline void store_u64(ATOMIC_U64 *ptr, uint64 value) |
| 90 | { |
| 91 | - my_atomic_store64((int64*) ptr, (int64) value); |
| 92 | + my_atomic_store64((ATOMIC_I64*) ptr, (int64) value); |
| 93 | } |
| 94 | |
| 95 | /** Atomic add. */ |
| 96 | @@ -89,7 +89,7 @@ public: |
| 97 | } |
| 98 | |
| 99 | /** Atomic add. */ |
| 100 | - static inline int64 add_64(int64 *ptr, int64 value) |
| 101 | + static inline int64 add_64(ATOMIC_I64 *ptr, int64 value) |
| 102 | { |
| 103 | return my_atomic_add64(ptr, value); |
| 104 | } |
| 105 | @@ -101,9 +101,9 @@ public: |
| 106 | } |
| 107 | |
| 108 | /** Atomic add. */ |
| 109 | - static inline uint64 add_u64(uint64 *ptr, uint64 value) |
| 110 | + static inline uint64 add_u64(ATOMIC_U64 *ptr, uint64 value) |
| 111 | { |
| 112 | - return (uint64) my_atomic_add64((int64*) ptr, (int64) value); |
| 113 | + return (uint64) my_atomic_add64((ATOMIC_I64*) ptr, (int64) value); |
| 114 | } |
| 115 | |
| 116 | /** Atomic compare and swap. */ |
| 117 | @@ -114,7 +114,7 @@ public: |
| 118 | } |
| 119 | |
| 120 | /** Atomic compare and swap. */ |
| 121 | - static inline bool cas_64(int64 *ptr, int64 *old_value, |
| 122 | + static inline bool cas_64(ATOMIC_I64 *ptr, ATOMIC_I64 *old_value, |
| 123 | int64 new_value) |
| 124 | { |
| 125 | return my_atomic_cas64(ptr, old_value, new_value); |
| 126 | @@ -129,10 +129,10 @@ public: |
| 127 | } |
| 128 | |
| 129 | /** Atomic compare and swap. */ |
| 130 | - static inline bool cas_u64(uint64 *ptr, uint64 *old_value, |
| 131 | + static inline bool cas_u64(ATOMIC_U64 *ptr, ATOMIC_U64 *old_value, |
| 132 | uint64 new_value) |
| 133 | { |
| 134 | - return my_atomic_cas64((int64*) ptr, (int64*) old_value, |
| 135 | + return my_atomic_cas64((ATOMIC_I64*) ptr, (ATOMIC_I64*) old_value, |
| 136 | (uint64) new_value); |
| 137 | } |
| 138 | }; |
| 139 | --- a/sql/sql_class.h |
| 140 | +++ b/sql/sql_class.h |
| 141 | @@ -1049,7 +1049,7 @@ static inline void update_global_memory_ |
| 142 | (longlong) global_status_var.global_memory_used, |
| 143 | size)); |
| 144 | // workaround for gcc 4.2.4-1ubuntu4 -fPIE (from DEB_BUILD_HARDENING=1) |
| 145 | - int64 volatile * volatile ptr= &global_status_var.global_memory_used; |
| 146 | + ATOMIC_I64 volatile * volatile ptr= &global_status_var.global_memory_used; |
| 147 | my_atomic_add64_explicit(ptr, size, MY_MEMORY_ORDER_RELAXED); |
| 148 | } |
| 149 | |
| 150 | --- a/storage/innobase/include/srv0mon.h |
| 151 | +++ b/storage/innobase/include/srv0mon.h |
| 152 | @@ -49,7 +49,7 @@ enum monitor_running_status { |
| 153 | typedef enum monitor_running_status monitor_running_t; |
| 154 | |
| 155 | /** Monitor counter value type */ |
| 156 | -typedef int64_t mon_type_t; |
| 157 | +typedef ATOMIC_I64 mon_type_t; |
| 158 | |
| 159 | /** Two monitor structures are defined in this file. One is |
| 160 | "monitor_value_t" which contains dynamic counter values for each |
| 161 | @@ -568,7 +568,7 @@ Use MONITOR_INC if appropriate mutex pro |
| 162 | if (enabled) { \ |
| 163 | ib_uint64_t value; \ |
| 164 | value = my_atomic_add64_explicit( \ |
| 165 | - (int64*) &MONITOR_VALUE(monitor), 1, \ |
| 166 | + (ATOMIC_I64*) &MONITOR_VALUE(monitor), 1, \ |
| 167 | MY_MEMORY_ORDER_RELAXED) + 1; \ |
| 168 | /* Note: This is not 100% accurate because of the \ |
| 169 | inherent race, we ignore it due to performance. */ \ |
| 170 | @@ -585,7 +585,7 @@ Use MONITOR_DEC if appropriate mutex pro |
| 171 | if (enabled) { \ |
| 172 | ib_uint64_t value; \ |
| 173 | value = my_atomic_add64_explicit( \ |
| 174 | - (int64*) &MONITOR_VALUE(monitor), -1, \ |
| 175 | + (ATOMIC_I64*) &MONITOR_VALUE(monitor), -1, \ |
| 176 | MY_MEMORY_ORDER_RELAXED) - 1; \ |
| 177 | /* Note: This is not 100% accurate because of the \ |
| 178 | inherent race, we ignore it due to performance. */ \ |