Coverage Report

Created: 2024-11-20 10:55

/var/local/thirdparty/installed/include/roaring/portability.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * portability.h
3
 *
4
 */
5
6
 /**
7
  * All macros should be prefixed with either CROARING or ROARING.
8
  * The library uses both ROARING_...
9
  * as well as CROAIRING_ as prefixes. The ROARING_ prefix is for
10
  * macros that are provided by the build system or that are closely
11
  * related to the format. The header macros may also use ROARING_.
12
  * The CROARING_ prefix is for internal macros that a user is unlikely
13
  * to ever interact with.
14
  */
15
16
#ifndef INCLUDE_PORTABILITY_H_
17
#define INCLUDE_PORTABILITY_H_
18
19
#ifndef _GNU_SOURCE
20
#define _GNU_SOURCE 1
21
#endif // _GNU_SOURCE
22
#ifndef __STDC_FORMAT_MACROS
23
#define __STDC_FORMAT_MACROS 1
24
#endif // __STDC_FORMAT_MACROS
25
26
#ifdef _MSC_VER
27
#define CROARING_VISUAL_STUDIO 1
28
/**
29
 * We want to differentiate carefully between
30
 * clang under visual studio and regular visual
31
 * studio.
32
 */
33
#ifdef __clang__
34
// clang under visual studio
35
#define CROARING_CLANG_VISUAL_STUDIO 1
36
#else
37
// just regular visual studio (best guess)
38
#define CROARING_REGULAR_VISUAL_STUDIO 1
39
#endif // __clang__
40
#endif // _MSC_VER
41
#ifndef CROARING_VISUAL_STUDIO
42
#define CROARING_VISUAL_STUDIO 0
43
#endif
44
#ifndef CROARING_CLANG_VISUAL_STUDIO
45
#define CROARING_CLANG_VISUAL_STUDIO 0
46
#endif
47
#ifndef CROARING_REGULAR_VISUAL_STUDIO
48
#define CROARING_REGULAR_VISUAL_STUDIO 0
49
#endif
50
51
#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 200809L)
52
#undef _POSIX_C_SOURCE
53
#endif
54
55
#ifndef _POSIX_C_SOURCE
56
#define _POSIX_C_SOURCE 200809L
57
#endif // !(defined(_POSIX_C_SOURCE)) || (_POSIX_C_SOURCE < 200809L)
58
#if !(defined(_XOPEN_SOURCE)) || (_XOPEN_SOURCE < 700)
59
#define _XOPEN_SOURCE 700
60
#endif // !(defined(_XOPEN_SOURCE)) || (_XOPEN_SOURCE < 700)
61
62
#ifdef __illumos__
63
#define __EXTENSIONS__
64
#endif
65
66
#include <stdbool.h>
67
#include <stdint.h>
68
#include <stdlib.h>  // will provide posix_memalign with _POSIX_C_SOURCE as defined above
69
#ifdef __GLIBC__
70
#include <malloc.h>  // this should never be needed but there are some reports that it is needed.
71
#endif
72
73
#ifdef __cplusplus
74
extern "C" {  // portability definitions are in global scope, not a namespace
75
#endif
76
77
#if defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ != 8
78
#error This code assumes  64-bit long longs (by use of the GCC intrinsics). Your system is not currently supported.
79
#endif
80
81
#if CROARING_REGULAR_VISUAL_STUDIO
82
#ifndef __restrict__
83
#define __restrict__ __restrict
84
#endif // __restrict__
85
#endif // CROARING_REGULAR_VISUAL_STUDIO
86
87
88
89
#if defined(__x86_64__) || defined(_M_X64)
90
// we have an x64 processor
91
#define CROARING_IS_X64 1
92
93
#if defined(_MSC_VER) && (_MSC_VER < 1910)
94
// Old visual studio systems won't support AVX2 well.
95
#undef CROARING_IS_X64
96
#endif
97
98
#if defined(__clang_major__) && (__clang_major__<= 8) && !defined(__AVX2__)
99
// Older versions of clang have a bug affecting us
100
// https://stackoverflow.com/questions/57228537/how-does-one-use-pragma-clang-attribute-push-with-c-namespaces
101
#undef CROARING_IS_X64
102
#endif
103
104
#ifdef ROARING_DISABLE_X64
105
#undef CROARING_IS_X64
106
#endif
107
// we include the intrinsic header
108
#if !CROARING_REGULAR_VISUAL_STUDIO
109
/* Non-Microsoft C/C++-compatible compiler */
110
#include <x86intrin.h>  // on some recent GCC, this will declare posix_memalign
111
112
113
114
#if CROARING_CLANG_VISUAL_STUDIO
115
116
/**
117
 * You are not supposed, normally, to include these
118
 * headers directly. Instead you should either include intrin.h
119
 * or x86intrin.h. However, when compiling with clang
120
 * under Windows (i.e., when _MSC_VER is set), these headers
121
 * only get included *if* the corresponding features are detected
122
 * from macros:
123
 * e.g., if __AVX2__ is set... in turn,  we normally set these
124
 * macros by compiling against the corresponding architecture
125
 * (e.g., arch:AVX2, -mavx2, etc.) which compiles the whole
126
 * software with these advanced instructions. These headers would
127
 * normally guard against such usage, but we carefully included
128
 * <x86intrin.h>  (or <intrin.h>) before, so the headers
129
 * are fooled.
130
 */
131
#include <bmiintrin.h>   // for _blsr_u64
132
#include <lzcntintrin.h> // for  __lzcnt64
133
#include <immintrin.h>   // for most things (AVX2, AVX512, _popcnt64)
134
#include <smmintrin.h>
135
#include <tmmintrin.h>
136
#include <avxintrin.h>
137
#include <avx2intrin.h>
138
#include <wmmintrin.h>
139
#if _MSC_VER >= 1920
140
// Important: we need the AVX-512 headers:
141
#include <avx512fintrin.h>
142
#include <avx512dqintrin.h>
143
#include <avx512cdintrin.h>
144
#include <avx512bwintrin.h>
145
#include <avx512vlintrin.h>
146
#include <avx512vbmiintrin.h>
147
#include <avx512vbmi2intrin.h>
148
#include <avx512vpopcntdqintrin.h>
149
#endif // _MSC_VER >= 1920
150
// unfortunately, we may not get _blsr_u64, but, thankfully, clang
151
// has it as a macro.
152
#ifndef _blsr_u64
153
// we roll our own
154
#define _blsr_u64(n) ((n - 1) & n)
155
#endif //  _blsr_u64
156
#endif // SIMDJSON_CLANG_VISUAL_STUDIO
157
158
159
#endif // CROARING_REGULAR_VISUAL_STUDIO
160
#endif // defined(__x86_64__) || defined(_M_X64)
161
162
#if !defined(CROARING_USENEON) && !defined(DISABLENEON) && defined(__ARM_NEON)
163
#  define CROARING_USENEON
164
#endif
165
#if defined(CROARING_USENEON)
166
#  include <arm_neon.h>
167
#endif
168
169
#if !CROARING_REGULAR_VISUAL_STUDIO
170
/* Non-Microsoft C/C++-compatible compiler, assumes that it supports inline
171
 * assembly */
172
#define CROARING_INLINE_ASM 1
173
#endif  // _MSC_VER
174
175
#if CROARING_REGULAR_VISUAL_STUDIO
176
/* Microsoft C/C++-compatible compiler */
177
#include <intrin.h>
178
179
#ifndef __clang__  // if one compiles with MSVC *with* clang, then these
180
                   // intrinsics are defined!!!
181
#define CROARING_INTRINSICS 1
182
// sadly there is no way to check whether we are missing these intrinsics
183
// specifically.
184
185
/* wrappers for Visual Studio built-ins that look like gcc built-ins __builtin_ctzll */
186
/* result might be undefined when input_num is zero */
187
inline int roaring_trailing_zeroes(unsigned long long input_num) {
188
    unsigned long index;
189
#ifdef _WIN64  // highly recommended!!!
190
    _BitScanForward64(&index, input_num);
191
#else  // if we must support 32-bit Windows
192
    if ((uint32_t)input_num != 0) {
193
        _BitScanForward(&index, (uint32_t)input_num);
194
    } else {
195
        _BitScanForward(&index, (uint32_t)(input_num >> 32));
196
        index += 32;
197
    }
198
#endif // _WIN64
199
    return index;
200
}
201
202
/* wrappers for Visual Studio built-ins that look like gcc built-ins __builtin_clzll */
203
/* result might be undefined when input_num is zero */
204
inline int roaring_leading_zeroes(unsigned long long input_num) {
205
    unsigned long index;
206
#ifdef _WIN64  // highly recommended!!!
207
    _BitScanReverse64(&index, input_num);
208
#else  // if we must support 32-bit Windows
209
    if (input_num > 0xFFFFFFFF) {
210
        _BitScanReverse(&index, (uint32_t)(input_num >> 32));
211
        index += 32;
212
    } else {
213
        _BitScanReverse(&index, (uint32_t)(input_num));
214
    }
215
#endif // _WIN64
216
    return 63 - index;
217
}
218
219
/* Use #define so this is effective even under /Ob0 (no inline) */
220
#define roaring_unreachable __assume(0)
221
#endif // __clang__
222
223
#endif // CROARING_REGULAR_VISUAL_STUDIO
224
225
#ifndef CROARING_INTRINSICS
226
#define CROARING_INTRINSICS 1
227
#define roaring_unreachable __builtin_unreachable()
228
0
inline int roaring_trailing_zeroes(unsigned long long input_num) { return __builtin_ctzll(input_num); }
229
0
inline int roaring_leading_zeroes(unsigned long long input_num) { return __builtin_clzll(input_num); }
230
#endif
231
232
#if CROARING_REGULAR_VISUAL_STUDIO
233
#define ALIGNED(x) __declspec(align(x))
234
#elif defined(__GNUC__) || defined(__clang__)
235
#define ALIGNED(x) __attribute__((aligned(x)))
236
#else
237
#warning "Warning. Unrecognized compiler."
238
#define ALIGNED(x)
239
#endif
240
241
#if defined(__GNUC__) || defined(__clang__)
242
#define WARN_UNUSED __attribute__((warn_unused_result))
243
#else
244
#define WARN_UNUSED
245
#endif
246
247
#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100)
248
249
#ifdef CROARING_USENEON
250
// we can always compute the popcount fast.
251
#elif (defined(_M_ARM) || defined(_M_ARM64)) && ((defined(_WIN64) || defined(_WIN32)) && defined(CROARING_REGULAR_VISUAL_STUDIO) && CROARING_REGULAR_VISUAL_STUDIO)
252
// we will need this function:
253
static inline int roaring_hamming_backup(uint64_t x) {
254
  uint64_t c1 = UINT64_C(0x5555555555555555);
255
  uint64_t c2 = UINT64_C(0x3333333333333333);
256
  uint64_t c4 = UINT64_C(0x0F0F0F0F0F0F0F0F);
257
  x -= (x >> 1) & c1;
258
  x = (( x >> 2) & c2) + (x & c2); x=(x +(x>>4))&c4;
259
  x *= UINT64_C(0x0101010101010101);
260
  return x >> 56;
261
}
262
#endif
263
264
265
0
static inline int roaring_hamming(uint64_t x) {
266
0
#if defined(_WIN64) && defined(CROARING_REGULAR_VISUAL_STUDIO) && CROARING_REGULAR_VISUAL_STUDIO
267
0
#ifdef CROARING_USENEON
268
0
   return vaddv_u8(vcnt_u8(vcreate_u8(input_num)));
269
0
#elif defined(_M_ARM64)
270
0
  return roaring_hamming_backup(x);
271
0
  // (int) _CountOneBits64(x); is unavailable
272
0
#else  // _M_ARM64
273
0
  return (int) __popcnt64(x);
274
0
#endif // _M_ARM64
275
0
#elif defined(_WIN32) && defined(CROARING_REGULAR_VISUAL_STUDIO) && CROARING_REGULAR_VISUAL_STUDIO
276
0
#ifdef _M_ARM
277
0
  return roaring_hamming_backup(x);
278
0
  // _CountOneBits is unavailable
279
0
#else // _M_ARM
280
0
    return (int) __popcnt(( unsigned int)x) + (int)  __popcnt(( unsigned int)(x>>32));
281
0
#endif // _M_ARM
282
0
#else
283
0
    return __builtin_popcountll(x);
284
0
#endif
285
0
}
Unexecuted instantiation: bkd_writer.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: bkd_reader.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: packed_index_tree.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: index_tree.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: legacy_index_tree.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: docids_writer.cpp:_ZL15roaring_hammingm
Unexecuted instantiation: IndexWriter.cpp:_ZL15roaring_hammingm
286
287
#ifndef UINT64_C
288
#define UINT64_C(c) (c##ULL)
289
#endif // UINT64_C
290
291
#ifndef UINT32_C
292
#define UINT32_C(c) (c##UL)
293
#endif // UINT32_C
294
295
#ifdef __cplusplus
296
}  // extern "C" {
297
#endif // __cplusplus
298
299
300
// this is almost standard?
301
#undef STRINGIFY_IMPLEMENTATION_
302
#undef STRINGIFY
303
#define STRINGIFY_IMPLEMENTATION_(a) #a
304
#define STRINGIFY(a) STRINGIFY_IMPLEMENTATION_(a)
305
306
// Our fast kernels require 64-bit systems.
307
//
308
// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions.
309
// Furthermore, the number of SIMD registers is reduced.
310
//
311
// On 32-bit ARM, we would have smaller registers.
312
//
313
// The library should still have the fallback kernel. It is
314
// slower, but it should run everywhere.
315
316
//
317
// Enable valid runtime implementations, and select CROARING_BUILTIN_IMPLEMENTATION
318
//
319
320
// We are going to use runtime dispatch.
321
#if CROARING_IS_X64
322
#ifdef __clang__
323
// clang does not have GCC push pop
324
// warning: clang attribute push can't be used within a namespace in clang up
325
// til 8.0 so CROARING_TARGET_REGION and CROARING_UNTARGET_REGION must be *outside* of a
326
// namespace.
327
#define CROARING_TARGET_REGION(T)                                                       \
328
  _Pragma(STRINGIFY(                                                           \
329
      clang attribute push(__attribute__((target(T))), apply_to = function)))
330
#define CROARING_UNTARGET_REGION _Pragma("clang attribute pop")
331
#elif defined(__GNUC__)
332
// GCC is easier
333
#define CROARING_TARGET_REGION(T)                                                       \
334
  _Pragma("GCC push_options") _Pragma(STRINGIFY(GCC target(T)))
335
#define CROARING_UNTARGET_REGION _Pragma("GCC pop_options")
336
#endif // clang then gcc
337
338
#endif // CROARING_IS_X64
339
340
// Default target region macros don't do anything.
341
#ifndef CROARING_TARGET_REGION
342
#define CROARING_TARGET_REGION(T)
343
#define CROARING_UNTARGET_REGION
344
#endif
345
346
347
#define CROARING_TARGET_AVX2 CROARING_TARGET_REGION("avx2,bmi,pclmul,lzcnt,popcnt")
348
#define CROARING_TARGET_AVX512 CROARING_TARGET_REGION("avx2,bmi,bmi2,pclmul,lzcnt,popcnt,avx512f,avx512dq,avx512bw,avx512vbmi2,avx512bitalg,avx512vpopcntdq")
349
#define CROARING_UNTARGET_AVX2 CROARING_UNTARGET_REGION
350
#define CROARING_UNTARGET_AVX512 CROARING_UNTARGET_REGION
351
352
#ifdef __AVX2__
353
// No need for runtime dispatching.
354
// It is unnecessary and harmful to old clang to tag regions.
355
#undef CROARING_TARGET_AVX2
356
#define CROARING_TARGET_AVX2
357
#undef CROARING_UNTARGET_AVX2
358
#define CROARING_UNTARGET_AVX2
359
#endif
360
361
#if defined(__AVX512F__) && defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VBMI2__) && defined(__AVX512BITALG__) && defined(__AVX512VPOPCNTDQ__)
362
// No need for runtime dispatching.
363
// It is unnecessary and harmful to old clang to tag regions.
364
#undef CROARING_TARGET_AVX512
365
#define CROARING_TARGET_AVX512
366
#undef CROARING_UNTARGET_AVX512
367
#define CROARING_UNTARGET_AVX512
368
#endif
369
370
// Allow unaligned memory access
371
#if defined(__GNUC__) || defined(__clang__)
372
#define ALLOW_UNALIGNED __attribute__((no_sanitize("alignment")))
373
#else
374
#define ALLOW_UNALIGNED
375
#endif
376
377
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
378
 #define CROARING_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
379
#elif defined(_WIN32)
380
 #define CROARING_IS_BIG_ENDIAN 0
381
 #else
382
 #if defined(__APPLE__) || defined(__FreeBSD__) // defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__
383
 #include <machine/endian.h>
384
 #elif defined(sun) || defined(__sun) // defined(__APPLE__) || defined(__FreeBSD__)
385
 #include <sys/byteorder.h>
386
 #else  // defined(__APPLE__) || defined(__FreeBSD__)
387
388
 #ifdef __has_include
389
 #if __has_include(<endian.h>)
390
 #include <endian.h>
391
 #endif //__has_include(<endian.h>)
392
 #endif //__has_include
393
394
 #endif // defined(__APPLE__) || defined(__FreeBSD__)
395
396
397
 #ifndef !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__)
398
 #define CROARING_IS_BIG_ENDIAN 0
399
 #endif
400
401
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
402
 #define CROARING_IS_BIG_ENDIAN 0
403
 #else // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
404
 #define CROARING_IS_BIG_ENDIAN 1
405
 #endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
406
#endif
407
408
// Defines for the possible CROARING atomic implementations
409
#define CROARING_ATOMIC_IMPL_NONE          1
410
#define CROARING_ATOMIC_IMPL_CPP           2
411
#define CROARING_ATOMIC_IMPL_C             3
412
#define CROARING_ATOMIC_IMPL_C_WINDOWS     4
413
414
// If the use has forced a specific implementation, use that, otherwise,
415
// figure out the best implementation we can use.
416
#if !defined(CROARING_ATOMIC_IMPL)
417
  #if defined(__cplusplus) && __cplusplus >= 201103L
418
    #ifdef __has_include
419
      #if __has_include(<atomic>)
420
        #define CROARING_ATOMIC_IMPL CROARING_ATOMIC_IMPL_CPP
421
      #endif //__has_include(<atomic>)
422
    #else
423
      // We lack __has_include to check:
424
      #define CROARING_ATOMIC_IMPL CROARING_ATOMIC_IMPL_CPP
425
    #endif //__has_include
426
  #elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
427
    #define CROARING_ATOMIC_IMPL CROARING_ATOMIC_IMPL_C
428
  #elif CROARING_REGULAR_VISUAL_STUDIO
429
    // https://www.technetworkhub.com/c11-atomics-in-visual-studio-2022-version-17/
430
    #define CROARING_ATOMIC_IMPL CROARING_ATOMIC_IMPL_C_WINDOWS
431
  #endif
432
#endif // !defined(CROARING_ATOMIC_IMPL)
433
434
#if CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_C
435
#include <stdatomic.h>
436
typedef _Atomic(uint32_t) croaring_refcount_t;
437
438
static inline void croaring_refcount_inc(croaring_refcount_t *val) {
439
    // Increasing the reference counter can always be done with
440
    // memory_order_relaxed: New references to an object can only be formed from
441
    // an existing reference, and passing an existing reference from one thread to
442
    // another must already provide any required synchronization.
443
    atomic_fetch_add_explicit(val, 1, memory_order_relaxed);
444
}
445
446
static inline bool croaring_refcount_dec(croaring_refcount_t *val) {
447
    // It is important to enforce any possible access to the object in one thread
448
    // (through an existing reference) to happen before deleting the object in a
449
    // different thread. This is achieved by a "release" operation after dropping
450
    // a reference (any access to the object through this reference must obviously
451
    // happened before), and an "acquire" operation before deleting the object.
452
    bool is_zero = atomic_fetch_sub_explicit(val, 1, memory_order_release) == 1;
453
    if (is_zero) {
454
        atomic_thread_fence(memory_order_acquire);
455
    }
456
    return is_zero;
457
}
458
459
static inline uint32_t croaring_refcount_get(const croaring_refcount_t *val) {
460
    return atomic_load_explicit(val, memory_order_relaxed);
461
}
462
#elif CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_CPP
463
#include <atomic>
464
typedef std::atomic<uint32_t> croaring_refcount_t;
465
466
0
static inline void croaring_refcount_inc(croaring_refcount_t *val) {
467
0
    val->fetch_add(1, std::memory_order_relaxed);
468
0
}
Unexecuted instantiation: bkd_writer.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: bkd_reader.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: packed_index_tree.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: index_tree.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: legacy_index_tree.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: docids_writer.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
Unexecuted instantiation: IndexWriter.cpp:_ZL21croaring_refcount_incPSt6atomicIjE
469
470
0
static inline bool croaring_refcount_dec(croaring_refcount_t *val) {
471
0
    // See above comments on the c11 atomic implementation for memory ordering
472
0
    bool is_zero = val->fetch_sub(1, std::memory_order_release) == 1;
473
0
    if (is_zero) {
474
0
        std::atomic_thread_fence(std::memory_order_acquire);
475
0
    }
476
0
    return is_zero;
477
0
}
Unexecuted instantiation: bkd_writer.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: bkd_reader.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: packed_index_tree.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: index_tree.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: legacy_index_tree.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: docids_writer.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
Unexecuted instantiation: IndexWriter.cpp:_ZL21croaring_refcount_decPSt6atomicIjE
478
479
0
static inline uint32_t croaring_refcount_get(const croaring_refcount_t *val) {
480
0
    return val->load(std::memory_order_relaxed);
481
0
}
Unexecuted instantiation: bkd_writer.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: bkd_reader.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: packed_index_tree.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: index_tree.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: legacy_index_tree.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: docids_writer.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
Unexecuted instantiation: IndexWriter.cpp:_ZL21croaring_refcount_getPKSt6atomicIjE
482
#elif CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_C_WINDOWS
483
#include <intrin.h>
484
#pragma intrinsic(_InterlockedIncrement)
485
#pragma intrinsic(_InterlockedDecrement)
486
487
// _InterlockedIncrement and _InterlockedDecrement take a (signed) long, and
488
// overflow is defined to wrap, so we can pretend it is a uint32_t for our case
489
typedef volatile long croaring_refcount_t;
490
491
static inline void croaring_refcount_inc(croaring_refcount_t *val) {
492
    _InterlockedIncrement(val);
493
}
494
495
static inline bool croaring_refcount_dec(croaring_refcount_t *val) {
496
    return _InterlockedDecrement(val) == 0;
497
}
498
499
static inline uint32_t croaring_refcount_get(const croaring_refcount_t *val) {
500
    // Per https://learn.microsoft.com/en-us/windows/win32/sync/interlocked-variable-access
501
    // > Simple reads and writes to properly-aligned 32-bit variables are atomic
502
    // > operations. In other words, you will not end up with only one portion
503
    // > of the variable updated; all bits are updated in an atomic fashion.
504
    return *val;
505
}
506
#elif CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_NONE
507
#include <assert.h>
508
typedef uint32_t croaring_refcount_t;
509
510
static inline void croaring_refcount_inc(croaring_refcount_t *val) {
511
    *val += 1;
512
}
513
514
static inline bool croaring_refcount_dec(croaring_refcount_t *val) {
515
    assert(*val > 0);
516
    *val -= 1;
517
    return val == 0;
518
}
519
520
static inline uint32_t croaring_refcount_get(const croaring_refcount_t *val) {
521
    return *val;
522
}
523
#else
524
#error "Unknown atomic implementation"
525
#endif
526
527
528
// We need portability.h to be included first,
529
// but we also always want isadetection.h to be
530
// included (right after).
531
// See https://github.com/RoaringBitmap/CRoaring/issues/394
532
// There is no scenario where we want portability.h to
533
// be included, but not isadetection.h: the latter is a
534
// strict requirement.
535
#include <roaring/isadetection.h> // include it last!
536
#endif /* INCLUDE_PORTABILITY_H_ */