Coverage Report

Created: 2020-09-15 12:33

/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/src/include/atomic_support.h
Line
Count
Source
1
//===----------------------------------------------------------------------===////
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===////
8
9
#ifndef ATOMIC_SUPPORT_H
10
#define ATOMIC_SUPPORT_H
11
12
#include "__config"
13
#include "memory" // for __libcpp_relaxed_load
14
15
#if defined(__clang__) && __has_builtin(__atomic_load_n)             \
16
                       && __has_builtin(__atomic_store_n)            \
17
                       && __has_builtin(__atomic_add_fetch)          \
18
                       && __has_builtin(__atomic_exchange_n)         \
19
                       && __has_builtin(__atomic_compare_exchange_n) \
20
                       && defined(__ATOMIC_RELAXED)                  \
21
                       && defined(__ATOMIC_CONSUME)                  \
22
                       && defined(__ATOMIC_ACQUIRE)                  \
23
                       && defined(__ATOMIC_RELEASE)                  \
24
                       && defined(__ATOMIC_ACQ_REL)                  \
25
                       && defined(__ATOMIC_SEQ_CST)
26
#   define _LIBCPP_HAS_ATOMIC_BUILTINS
27
#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
28
#   define _LIBCPP_HAS_ATOMIC_BUILTINS
29
#endif
30
31
#if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
32
# if defined(_LIBCPP_WARNING)
33
    _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported")
34
# else
35
#   warning Building libc++ without __atomic builtins is unsupported
36
# endif
37
#endif
38
39
_LIBCPP_BEGIN_NAMESPACE_STD
40
41
namespace {
42
43
#if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
44
45
enum __libcpp_atomic_order {
46
    _AO_Relaxed = __ATOMIC_RELAXED,
47
    _AO_Consume = __ATOMIC_CONSUME,
48
    _AO_Acquire = __ATOMIC_ACQUIRE,
49
    _AO_Release = __ATOMIC_RELEASE,
50
    _AO_Acq_Rel = __ATOMIC_ACQ_REL,
51
    _AO_Seq     = __ATOMIC_SEQ_CST
52
};
53
54
template <class _ValueType, class _FromType>
55
inline _LIBCPP_INLINE_VISIBILITY
56
void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
57
                           int __order = _AO_Seq)
58
393k
{
59
393k
    __atomic_store_n(__dest, __val, __order);
60
393k
}
61
62
template <class _ValueType, class _FromType>
63
inline _LIBCPP_INLINE_VISIBILITY
64
void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
65
393k
{
66
393k
    __atomic_store_n(__dest, __val, _AO_Relaxed);
67
393k
}
68
69
template <class _ValueType>
70
inline _LIBCPP_INLINE_VISIBILITY
71
_ValueType __libcpp_atomic_load(_ValueType const* __val,
72
                                int __order = _AO_Seq)
73
30.9M
{
74
30.9M
    return __atomic_load_n(__val, __order);
75
30.9M
}
76
77
template <class _ValueType, class _AddType>
78
inline _LIBCPP_INLINE_VISIBILITY
79
_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
80
                               int __order = _AO_Seq)
81
372k
{
82
372k
    return __atomic_add_fetch(__val, __a, __order);
83
372k
}
locale.cpp:int std::__1::(anonymous namespace)::__libcpp_atomic_add<int, int>(int*, int, int)
Line
Count
Source
81
372k
{
82
372k
    return __atomic_add_fetch(__val, __a, __order);
83
372k
}
Unexecuted instantiation: stdexcept.cpp:int std::__1::(anonymous namespace)::__libcpp_atomic_add<int, int>(int*, int, int)
84
85
template <class _ValueType>
86
inline _LIBCPP_INLINE_VISIBILITY
87
_ValueType __libcpp_atomic_exchange(_ValueType* __target,
88
                                    _ValueType __value, int __order = _AO_Seq)
89
{
90
    return __atomic_exchange_n(__target, __value, __order);
91
}
92
93
template <class _ValueType>
94
inline _LIBCPP_INLINE_VISIBILITY
95
bool __libcpp_atomic_compare_exchange(_ValueType* __val,
96
    _ValueType* __expected, _ValueType __after,
97
    int __success_order = _AO_Seq,
98
    int __fail_order = _AO_Seq)
99
25.0M
{
100
25.0M
    return __atomic_compare_exchange_n(__val, __expected, __after, true,
101
25.0M
                                       __success_order, __fail_order);
102
25.0M
}
103
104
#else // _LIBCPP_HAS_NO_THREADS
105
106
enum __libcpp_atomic_order {
107
    _AO_Relaxed,
108
    _AO_Consume,
109
    _AO_Acquire,
110
    _AO_Release,
111
    _AO_Acq_Rel,
112
    _AO_Seq
113
};
114
115
template <class _ValueType, class _FromType>
116
inline _LIBCPP_INLINE_VISIBILITY
117
void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
118
                           int = 0)
119
{
120
    *__dest = __val;
121
}
122
123
template <class _ValueType, class _FromType>
124
inline _LIBCPP_INLINE_VISIBILITY
125
void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
126
{
127
    *__dest = __val;
128
}
129
130
template <class _ValueType>
131
inline _LIBCPP_INLINE_VISIBILITY
132
_ValueType __libcpp_atomic_load(_ValueType const* __val,
133
                                int = 0)
134
{
135
    return *__val;
136
}
137
138
template <class _ValueType, class _AddType>
139
inline _LIBCPP_INLINE_VISIBILITY
140
_ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
141
                               int = 0)
142
{
143
    return *__val += __a;
144
}
145
146
template <class _ValueType>
147
inline _LIBCPP_INLINE_VISIBILITY
148
_ValueType __libcpp_atomic_exchange(_ValueType* __target,
149
                                    _ValueType __value, int __order = _AO_Seq)
150
{
151
    _ValueType old = *__target;
152
    *__target = __value;
153
    return old;
154
}
155
156
template <class _ValueType>
157
inline _LIBCPP_INLINE_VISIBILITY
158
bool __libcpp_atomic_compare_exchange(_ValueType* __val,
159
    _ValueType* __expected, _ValueType __after,
160
    int = 0, int = 0)
161
{
162
    if (*__val == *__expected) {
163
        *__val = __after;
164
        return true;
165
    }
166
    *__expected = *__val;
167
    return false;
168
}
169
170
#endif // _LIBCPP_HAS_NO_THREADS
171
172
} // end namespace
173
174
_LIBCPP_END_NAMESPACE_STD
175
176
#endif // ATOMIC_SUPPORT_H