| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/util/atomic.h |
| Date: | 2025-11-30 02:35:17 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 41 | 43 | 95.3% |
| Branches: | 8 | 8 | 100.0% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * This file is part of the CernVM File System. | ||
| 3 | * | ||
| 4 | * Defines wrapper functions for atomic integer operations. Atomic operations | ||
| 5 | * are handled by GCC. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CVMFS_UTIL_ATOMIC_H_ | ||
| 9 | #define CVMFS_UTIL_ATOMIC_H_ | ||
| 10 | |||
| 11 | #include <stdint.h> | ||
| 12 | |||
| 13 | #ifdef CVMFS_NAMESPACE_GUARD | ||
| 14 | namespace CVMFS_NAMESPACE_GUARD { | ||
| 15 | #endif | ||
| 16 | |||
| 17 | typedef int32_t atomic_int32; | ||
| 18 | typedef int64_t atomic_int64; | ||
| 19 | |||
| 20 | 13796844 | static void inline __attribute__((used)) atomic_init32(atomic_int32 *a) { | |
| 21 | 13796844 | *a = 0; | |
| 22 | 13796844 | } | |
| 23 | |||
| 24 | 11830482 | static void inline __attribute__((used)) atomic_init64(atomic_int64 *a) { | |
| 25 | 11830482 | *a = 0; | |
| 26 | 11830482 | } | |
| 27 | |||
| 28 | 1063538405 | static int32_t inline __attribute__((used)) atomic_read32(atomic_int32 *a) { | |
| 29 | 1063538405 | return __sync_fetch_and_add(a, 0); | |
| 30 | } | ||
| 31 | |||
| 32 | 706566210 | static int64_t inline __attribute__((used)) atomic_read64(atomic_int64 *a) { | |
| 33 | 706566210 | return __sync_fetch_and_add(a, 0); | |
| 34 | } | ||
| 35 | |||
| 36 | 222434355 | static void inline __attribute__((used)) atomic_write32(atomic_int32 *a, | |
| 37 | int32_t value) { | ||
| 38 |
2/2✓ Branch 1 taken 395272530 times.
✓ Branch 2 taken 268698390 times.
|
617706885 | while (!__sync_bool_compare_and_swap(a, atomic_read32(a), value)) { |
| 39 | } | ||
| 40 | 268698390 | } | |
| 41 | |||
| 42 | 209485123 | static void inline __attribute__((used)) atomic_write64(atomic_int64 *a, | |
| 43 | int64_t value) { | ||
| 44 |
2/2✓ Branch 1 taken 463047105 times.
✓ Branch 2 taken 257593933 times.
|
672532228 | while (!__sync_bool_compare_and_swap(a, atomic_read64(a), value)) { |
| 45 | } | ||
| 46 | 257593933 | } | |
| 47 | |||
| 48 | 123099751 | static void inline __attribute__((used)) atomic_inc32(atomic_int32 *a) { | |
| 49 | 123099751 | (void)__sync_fetch_and_add(a, 1); | |
| 50 | 123099751 | } | |
| 51 | |||
| 52 | 169454239 | static void inline __attribute__((used)) atomic_inc64(atomic_int64 *a) { | |
| 53 | 169454239 | (void)__sync_fetch_and_add(a, 1); | |
| 54 | 169454239 | } | |
| 55 | |||
| 56 | 79526220 | static void inline __attribute__((used)) atomic_dec32(atomic_int32 *a) { | |
| 57 | 79526220 | (void)__sync_fetch_and_sub(a, 1); | |
| 58 | 79526220 | } | |
| 59 | |||
| 60 | 67025122 | static void inline __attribute__((used)) atomic_dec64(atomic_int64 *a) { | |
| 61 | 67025122 | (void)__sync_fetch_and_sub(a, 1); | |
| 62 | 67025122 | } | |
| 63 | |||
| 64 | 33762564 | static int32_t inline __attribute__((used)) atomic_xadd32(atomic_int32 *a, | |
| 65 | int32_t offset) { | ||
| 66 |
2/2✓ Branch 0 taken 1062887 times.
✓ Branch 1 taken 32699677 times.
|
33762564 | if (offset < 0) |
| 67 | 1062887 | return __sync_fetch_and_sub(a, -offset); | |
| 68 | 32699682 | return __sync_fetch_and_add(a, offset); | |
| 69 | } | ||
| 70 | |||
| 71 | 156134972 | static int64_t inline __attribute__((used)) atomic_xadd64(atomic_int64 *a, | |
| 72 | int64_t offset) { | ||
| 73 |
2/2✓ Branch 0 taken 36923707 times.
✓ Branch 1 taken 119211265 times.
|
156134972 | if (offset < 0) |
| 74 | 36923707 | return __sync_fetch_and_sub(a, -offset); | |
| 75 | 119211265 | return __sync_fetch_and_add(a, offset); | |
| 76 | } | ||
| 77 | |||
| 78 | 4183915 | static bool inline __attribute__((used)) atomic_cas32(atomic_int32 *a, | |
| 79 | int32_t cmp, | ||
| 80 | int32_t newval) { | ||
| 81 | 4183915 | return __sync_bool_compare_and_swap(a, cmp, newval); | |
| 82 | } | ||
| 83 | |||
| 84 | ✗ | static bool inline __attribute__((used)) atomic_cas64(atomic_int64 *a, | |
| 85 | int64_t cmp, | ||
| 86 | int64_t newval) { | ||
| 87 | // Clang 3.5 has a bug in optimized __sync_bool_compare_and_swap: | ||
| 88 | // https://bugs.llvm.org//show_bug.cgi?format=multiple&id=21499 | ||
| 89 | ✗ | return __sync_bool_compare_and_swap(a, cmp, newval); | |
| 90 | } | ||
| 91 | |||
| 92 | 852 | static void inline __attribute__((used)) MemoryFence() { | |
| 93 | 852 | asm __volatile__("" : : : "memory"); | |
| 94 | 852 | } | |
| 95 | |||
| 96 | #ifdef CVMFS_NAMESPACE_GUARD | ||
| 97 | } // namespace CVMFS_NAMESPACE_GUARD | ||
| 98 | #endif | ||
| 99 | |||
| 100 | #endif // CVMFS_UTIL_ATOMIC_H_ | ||
| 101 |