Coverage Report

Created: 2026-06-10 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/librdkafka/src/rdatomic.h
Line
Count
Source
1
/*
2
 * librdkafka - The Apache Kafka C/C++ library
3
 *
4
 * Copyright (c) 2014-2022, Magnus Edenhill
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright notice,
11
 *    this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright notice,
13
 *    this list of conditions and the following disclaimer in the documentation
14
 *    and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
 * POSSIBILITY OF SUCH DAMAGE.
27
 */
28
#ifndef _RDATOMIC_H_
29
#define _RDATOMIC_H_
30
31
#include "tinycthread.h"
32
33
typedef struct {
34
        int32_t val;
35
#if !defined(_WIN32) && !HAVE_ATOMICS_32
36
        mtx_t lock;
37
#endif
38
} rd_atomic32_t;
39
40
typedef struct {
41
        int64_t val;
42
#if !defined(_WIN32) && !HAVE_ATOMICS_64
43
        mtx_t lock;
44
#endif
45
} rd_atomic64_t;
46
47
48
0
static RD_INLINE RD_UNUSED void rd_atomic32_init(rd_atomic32_t *ra, int32_t v) {
49
0
        ra->val = v;
50
0
#if !defined(_WIN32) && !HAVE_ATOMICS_32
51
0
        mtx_init(&ra->lock, mtx_plain);
52
0
#endif
53
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic32_init
Unexecuted instantiation: regexp.c:rd_atomic32_init
54
55
56
static RD_INLINE int32_t RD_UNUSED rd_atomic32_add(rd_atomic32_t *ra,
57
0
                                                   int32_t v) {
58
0
#ifdef __SUNPRO_C
59
0
        return atomic_add_32_nv(&ra->val, v);
60
0
#elif defined(_WIN32)
61
0
        return InterlockedAdd((LONG *)&ra->val, v);
62
0
#elif !HAVE_ATOMICS_32
63
0
        int32_t r;
64
0
        mtx_lock(&ra->lock);
65
0
        ra->val += v;
66
0
        r = ra->val;
67
0
        mtx_unlock(&ra->lock);
68
0
        return r;
69
0
#else
70
0
        return ATOMIC_OP32(add, fetch, &ra->val, v);
71
0
#endif
72
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic32_add
Unexecuted instantiation: regexp.c:rd_atomic32_add
73
74
static RD_INLINE int32_t RD_UNUSED rd_atomic32_sub(rd_atomic32_t *ra,
75
0
                                                   int32_t v) {
76
0
#ifdef __SUNPRO_C
77
0
        return atomic_add_32_nv(&ra->val, -v);
78
0
#elif defined(_WIN32)
79
0
        return InterlockedAdd((LONG *)&ra->val, -v);
80
0
#elif !HAVE_ATOMICS_32
81
0
        int32_t r;
82
0
        mtx_lock(&ra->lock);
83
0
        ra->val -= v;
84
0
        r = ra->val;
85
0
        mtx_unlock(&ra->lock);
86
0
        return r;
87
0
#else
88
0
        return ATOMIC_OP32(sub, fetch, &ra->val, v);
89
0
#endif
90
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic32_sub
Unexecuted instantiation: regexp.c:rd_atomic32_sub
91
92
/**
93
 * @warning The returned value is the nominal value and will be outdated
94
 *          by the time the application reads it.
95
 *          It should not be used for exact arithmetics, any correlation
96
 *          with other data is unsynchronized, meaning that two atomics,
97
 *          or one atomic and a mutex-protected piece of data have no
98
 *          common synchronization and can't be relied on.
99
 */
100
0
static RD_INLINE int32_t RD_UNUSED rd_atomic32_get(rd_atomic32_t *ra) {
101
0
#if defined(_WIN32) || defined(__SUNPRO_C)
102
0
        return ra->val;
103
0
#elif !HAVE_ATOMICS_32
104
0
        int32_t r;
105
0
        mtx_lock(&ra->lock);
106
0
        r = ra->val;
107
0
        mtx_unlock(&ra->lock);
108
0
        return r;
109
0
#else
110
0
        return ATOMIC_OP32(fetch, add, &ra->val, 0);
111
0
#endif
112
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic32_get
Unexecuted instantiation: regexp.c:rd_atomic32_get
113
114
/**
115
 * @brief Set the atomic value to \p v and return the previous value to
116
 *        that can be used to determine if the value was changed.
117
 */
118
static RD_INLINE int32_t RD_UNUSED rd_atomic32_set(rd_atomic32_t *ra,
119
0
                                                   int32_t v) {
120
0
#ifdef _WIN32
121
0
        return InterlockedExchange((LONG *)&ra->val, v);
122
0
#elif !HAVE_ATOMICS_32
123
0
        int32_t r;
124
0
        mtx_lock(&ra->lock);
125
0
        r       = rd->val;
126
0
        ra->val = v;
127
0
        mtx_unlock(&ra->lock);
128
0
        return r;
129
0
#elif HAVE_ATOMICS_32_ATOMIC
130
0
        return __atomic_exchange_n(&ra->val, v, __ATOMIC_SEQ_CST);
131
0
#elif HAVE_ATOMICS_32_SYNC
132
0
        return __sync_lock_test_and_set(&ra->val, v);
133
0
#else
134
0
        return ra->val = v;  // FIXME
135
0
#endif
136
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic32_set
Unexecuted instantiation: regexp.c:rd_atomic32_set
137
138
139
140
0
static RD_INLINE RD_UNUSED void rd_atomic64_init(rd_atomic64_t *ra, int64_t v) {
141
0
        ra->val = v;
142
0
#if !defined(_WIN32) && !HAVE_ATOMICS_64
143
0
        mtx_init(&ra->lock, mtx_plain);
144
0
#endif
145
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic64_init
Unexecuted instantiation: regexp.c:rd_atomic64_init
146
147
static RD_INLINE int64_t RD_UNUSED rd_atomic64_add(rd_atomic64_t *ra,
148
0
                                                   int64_t v) {
149
0
#ifdef __SUNPRO_C
150
0
        return atomic_add_64_nv(&ra->val, v);
151
0
#elif defined(_WIN32)
152
0
        return InterlockedAdd64(&ra->val, v);
153
0
#elif !HAVE_ATOMICS_64
154
0
        int64_t r;
155
0
        mtx_lock(&ra->lock);
156
0
        ra->val += v;
157
0
        r = ra->val;
158
0
        mtx_unlock(&ra->lock);
159
0
        return r;
160
0
#else
161
0
        return ATOMIC_OP64(add, fetch, &ra->val, v);
162
0
#endif
163
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic64_add
Unexecuted instantiation: regexp.c:rd_atomic64_add
164
165
static RD_INLINE int64_t RD_UNUSED rd_atomic64_sub(rd_atomic64_t *ra,
166
0
                                                   int64_t v) {
167
0
#ifdef __SUNPRO_C
168
0
        return atomic_add_64_nv(&ra->val, -v);
169
0
#elif defined(_WIN32)
170
0
        return InterlockedAdd64(&ra->val, -v);
171
0
#elif !HAVE_ATOMICS_64
172
0
        int64_t r;
173
0
        mtx_lock(&ra->lock);
174
0
        ra->val -= v;
175
0
        r = ra->val;
176
0
        mtx_unlock(&ra->lock);
177
0
        return r;
178
0
#else
179
0
        return ATOMIC_OP64(sub, fetch, &ra->val, v);
180
0
#endif
181
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic64_sub
Unexecuted instantiation: regexp.c:rd_atomic64_sub
182
183
/**
184
 * @warning The returned value is the nominal value and will be outdated
185
 *          by the time the application reads it.
186
 *          It should not be used for exact arithmetics, any correlation
187
 *          with other data is unsynchronized, meaning that two atomics,
188
 *          or one atomic and a mutex-protected piece of data have no
189
 *          common synchronization and can't be relied on.
190
 *          Use with care.
191
 */
192
0
static RD_INLINE int64_t RD_UNUSED rd_atomic64_get(rd_atomic64_t *ra) {
193
0
#if defined(_WIN32) || defined(__SUNPRO_C)
194
0
        return InterlockedCompareExchange64(&ra->val, 0, 0);
195
0
#elif !HAVE_ATOMICS_64
196
0
        int64_t r;
197
0
        mtx_lock(&ra->lock);
198
0
        r = ra->val;
199
0
        mtx_unlock(&ra->lock);
200
0
        return r;
201
0
#else
202
0
        return ATOMIC_OP64(fetch, add, &ra->val, 0);
203
0
#endif
204
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic64_get
Unexecuted instantiation: regexp.c:rd_atomic64_get
205
206
/**
207
 * @brief Set the atomic value to \p v and return the previous value to
208
 *        that can be used to determine if the value was changed.
209
 */
210
static RD_INLINE int64_t RD_UNUSED rd_atomic64_set(rd_atomic64_t *ra,
211
0
                                                   int64_t v) {
212
0
#ifdef _WIN32
213
0
        return InterlockedExchange64(&ra->val, v);
214
0
#elif !HAVE_ATOMICS_64
215
0
        int64_t r;
216
0
        mtx_lock(&ra->lock);
217
0
        r       = ra->val;
218
0
        ra->val = v;
219
0
        mtx_unlock(&ra->lock);
220
0
        return r;
221
0
#elif HAVE_ATOMICS_64_ATOMIC
222
0
        return __atomic_exchange_n(&ra->val, v, __ATOMIC_SEQ_CST);
223
0
#elif HAVE_ATOMICS_64_SYNC
224
0
        return __sync_lock_test_and_set(&ra->val, v);
225
0
#else
226
0
        return ra->val = v;  // FIXME
227
0
#endif
228
0
}
Unexecuted instantiation: fuzz_regex.c:rd_atomic64_set
Unexecuted instantiation: regexp.c:rd_atomic64_set
229
230
#endif /* _RDATOMIC_H_ */