Coverage Report

Created: 2024-09-06 07:53

/src/libvpx/vpx_util/vpx_atomics.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Copyright (c) 2017 The WebM project authors. All Rights Reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
9
 */
10
11
#ifndef VPX_VPX_UTIL_VPX_ATOMICS_H_
12
#define VPX_VPX_UTIL_VPX_ATOMICS_H_
13
14
#include "./vpx_config.h"
15
16
#ifdef __cplusplus
17
extern "C" {
18
#endif  // __cplusplus
19
20
#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD
21
22
// Look for built-in atomic support. We cannot use <stdatomic.h> or <atomic>
23
// since neither is guaranteed to exist on both C and C++ platforms, and we need
24
// to back the atomic type with the same type (g++ needs to be able to use
25
// gcc-built code). g++ 6 doesn't support _Atomic as a keyword and can't use the
26
// stdatomic.h header. Even if both <stdatomic.h> and <atomic> existed it's not
27
// guaranteed that atomic_int is the same type as std::atomic_int.
28
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932#c13.
29
#if !defined(__has_builtin)
30
#define __has_builtin(x) 0  // Compatibility with non-clang compilers.
31
#endif                      // !defined(__has_builtin)
32
33
#if (__has_builtin(__atomic_load_n)) || \
34
    (defined(__GNUC__) &&               \
35
     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)))
36
// For GCC >= 4.7 and Clang versions that support __atomic builtins, use those.
37
#define VPX_USE_ATOMIC_BUILTINS
38
#else
39
// Use platform-specific asm barriers.
40
#if defined(_MSC_VER)
41
// TODO(pbos): This assumes that newer versions of MSVC are building with the
42
// default /volatile:ms (or older, where this is always true. Consider adding
43
// support for using <atomic> instead of stdatomic.h when building C++11 under
44
// MSVC. It's unclear what to do for plain C under /volatile:iso (inline asm?),
45
// there're no explicit Interlocked* functions for only storing or loading
46
// (presumably because volatile has historically implied that on MSVC).
47
//
48
// For earlier versions of MSVC or the default /volatile:ms volatile int are
49
// acquire/release and require no barrier.
50
#define vpx_atomic_memory_barrier() \
51
  do {                              \
52
  } while (0)
53
#else
54
#if VPX_ARCH_X86 || VPX_ARCH_X86_64
55
// Use a compiler barrier on x86, no runtime penalty.
56
#define vpx_atomic_memory_barrier() __asm__ __volatile__("" ::: "memory")
57
#elif VPX_ARCH_ARM
58
#define vpx_atomic_memory_barrier() __asm__ __volatile__("dmb ish" ::: "memory")
59
#elif VPX_ARCH_MIPS
60
#define vpx_atomic_memory_barrier() __asm__ __volatile__("sync" ::: "memory")
61
#else
62
#error Unsupported architecture!
63
#endif  // VPX_ARCH_X86 || VPX_ARCH_X86_64
64
#endif  // defined(_MSC_VER)
65
#endif  // atomic builtin availability check
66
67
// These are wrapped in a struct so that they are not easily accessed directly
68
// on any platform (to discourage programmer errors by setting values directly).
69
// This primitive MUST be initialized using vpx_atomic_init or VPX_ATOMIC_INIT
70
// (NOT memset) and accessed through vpx_atomic_ functions.
71
typedef struct vpx_atomic_int {
72
  volatile int value;
73
} vpx_atomic_int;
74
75
#define VPX_ATOMIC_INIT(num) \
76
328k
  { num }
77
78
// Initialization of an atomic int, not thread safe.
79
0
static INLINE void vpx_atomic_init(vpx_atomic_int *atomic, int value) {
80
0
  atomic->value = value;
81
0
}
Unexecuted instantiation: vp8_cx_iface.c:vpx_atomic_init
Unexecuted instantiation: ethreading.c:vpx_atomic_init
Unexecuted instantiation: onyx_if.c:vpx_atomic_init
Unexecuted instantiation: pickinter.c:vpx_atomic_init
Unexecuted instantiation: picklpf.c:vpx_atomic_init
Unexecuted instantiation: vp8_quantize.c:vpx_atomic_init
Unexecuted instantiation: ratectrl.c:vpx_atomic_init
Unexecuted instantiation: rdopt.c:vpx_atomic_init
Unexecuted instantiation: segmentation.c:vpx_atomic_init
Unexecuted instantiation: vp8_skin_detection.c:vpx_atomic_init
Unexecuted instantiation: tokenize.c:vpx_atomic_init
Unexecuted instantiation: temporal_filter.c:vpx_atomic_init
Unexecuted instantiation: bitstream.c:vpx_atomic_init
Unexecuted instantiation: encodeframe.c:vpx_atomic_init
Unexecuted instantiation: encodeintra.c:vpx_atomic_init
Unexecuted instantiation: encodemb.c:vpx_atomic_init
Unexecuted instantiation: encodemv.c:vpx_atomic_init
Unexecuted instantiation: firstpass.c:vpx_atomic_init
Unexecuted instantiation: mcomp.c:vpx_atomic_init
Unexecuted instantiation: modecosts.c:vpx_atomic_init
82
83
0
static INLINE void vpx_atomic_store_release(vpx_atomic_int *atomic, int value) {
84
0
#if defined(VPX_USE_ATOMIC_BUILTINS)
85
0
  __atomic_store_n(&atomic->value, value, __ATOMIC_RELEASE);
86
#else
87
  vpx_atomic_memory_barrier();
88
  atomic->value = value;
89
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
90
0
}
Unexecuted instantiation: vp8_cx_iface.c:vpx_atomic_store_release
Unexecuted instantiation: ethreading.c:vpx_atomic_store_release
Unexecuted instantiation: onyx_if.c:vpx_atomic_store_release
Unexecuted instantiation: pickinter.c:vpx_atomic_store_release
Unexecuted instantiation: picklpf.c:vpx_atomic_store_release
Unexecuted instantiation: vp8_quantize.c:vpx_atomic_store_release
Unexecuted instantiation: ratectrl.c:vpx_atomic_store_release
Unexecuted instantiation: rdopt.c:vpx_atomic_store_release
Unexecuted instantiation: segmentation.c:vpx_atomic_store_release
Unexecuted instantiation: vp8_skin_detection.c:vpx_atomic_store_release
Unexecuted instantiation: tokenize.c:vpx_atomic_store_release
Unexecuted instantiation: temporal_filter.c:vpx_atomic_store_release
Unexecuted instantiation: bitstream.c:vpx_atomic_store_release
Unexecuted instantiation: encodeframe.c:vpx_atomic_store_release
Unexecuted instantiation: encodeintra.c:vpx_atomic_store_release
Unexecuted instantiation: encodemb.c:vpx_atomic_store_release
Unexecuted instantiation: encodemv.c:vpx_atomic_store_release
Unexecuted instantiation: firstpass.c:vpx_atomic_store_release
Unexecuted instantiation: mcomp.c:vpx_atomic_store_release
Unexecuted instantiation: modecosts.c:vpx_atomic_store_release
91
92
3.51M
static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) {
93
3.51M
#if defined(VPX_USE_ATOMIC_BUILTINS)
94
3.51M
  return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE);
95
#else
96
  int v = atomic->value;
97
  vpx_atomic_memory_barrier();
98
  return v;
99
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
100
3.51M
}
Unexecuted instantiation: vp8_cx_iface.c:vpx_atomic_load_acquire
ethreading.c:vpx_atomic_load_acquire
Line
Count
Source
92
4.91k
static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) {
93
4.91k
#if defined(VPX_USE_ATOMIC_BUILTINS)
94
4.91k
  return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE);
95
#else
96
  int v = atomic->value;
97
  vpx_atomic_memory_barrier();
98
  return v;
99
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
100
4.91k
}
onyx_if.c:vpx_atomic_load_acquire
Line
Count
Source
92
210k
static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) {
93
210k
#if defined(VPX_USE_ATOMIC_BUILTINS)
94
210k
  return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE);
95
#else
96
  int v = atomic->value;
97
  vpx_atomic_memory_barrier();
98
  return v;
99
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
100
210k
}
Unexecuted instantiation: pickinter.c:vpx_atomic_load_acquire
Unexecuted instantiation: picklpf.c:vpx_atomic_load_acquire
Unexecuted instantiation: vp8_quantize.c:vpx_atomic_load_acquire
Unexecuted instantiation: ratectrl.c:vpx_atomic_load_acquire
Unexecuted instantiation: rdopt.c:vpx_atomic_load_acquire
Unexecuted instantiation: segmentation.c:vpx_atomic_load_acquire
Unexecuted instantiation: vp8_skin_detection.c:vpx_atomic_load_acquire
Unexecuted instantiation: tokenize.c:vpx_atomic_load_acquire
Unexecuted instantiation: temporal_filter.c:vpx_atomic_load_acquire
bitstream.c:vpx_atomic_load_acquire
Line
Count
Source
92
70.0k
static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) {
93
70.0k
#if defined(VPX_USE_ATOMIC_BUILTINS)
94
70.0k
  return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE);
95
#else
96
  int v = atomic->value;
97
  vpx_atomic_memory_barrier();
98
  return v;
99
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
100
70.0k
}
encodeframe.c:vpx_atomic_load_acquire
Line
Count
Source
92
3.23M
static INLINE int vpx_atomic_load_acquire(const vpx_atomic_int *atomic) {
93
3.23M
#if defined(VPX_USE_ATOMIC_BUILTINS)
94
3.23M
  return __atomic_load_n(&atomic->value, __ATOMIC_ACQUIRE);
95
#else
96
  int v = atomic->value;
97
  vpx_atomic_memory_barrier();
98
  return v;
99
#endif  // defined(VPX_USE_ATOMIC_BUILTINS)
100
3.23M
}
Unexecuted instantiation: encodeintra.c:vpx_atomic_load_acquire
Unexecuted instantiation: encodemb.c:vpx_atomic_load_acquire
Unexecuted instantiation: encodemv.c:vpx_atomic_load_acquire
Unexecuted instantiation: firstpass.c:vpx_atomic_load_acquire
Unexecuted instantiation: mcomp.c:vpx_atomic_load_acquire
Unexecuted instantiation: modecosts.c:vpx_atomic_load_acquire
101
102
#undef VPX_USE_ATOMIC_BUILTINS
103
#undef vpx_atomic_memory_barrier
104
105
#endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */
106
107
#ifdef __cplusplus
108
}  // extern "C"
109
#endif  // __cplusplus
110
111
#endif  // VPX_VPX_UTIL_VPX_ATOMICS_H_