[med-svn] [Git][med-team/libatomic-queue][upstream] New upstream version 1.6.9
Stephan Lachnit (@stephanlachnit)
gitlab at salsa.debian.org
Tue Jun 24 20:12:22 BST 2025
Stephan Lachnit pushed to branch upstream at Debian Med / libatomic-queue
Commits:
f2b7705e by Stephan Lachnit at 2025-06-24T20:31:38+02:00
New upstream version 1.6.9
- - - - -
10 changed files:
- + .github/workflows/ci-meson.yml
- .github/workflows/ci.yml
- CONTRIBUTORS.txt
- Makefile
- README.md
- include/atomic_queue/atomic_queue.h
- include/atomic_queue/defs.h
- meson.build
- meson_options.txt
- src/tests.cc
Changes:
=====================================
.github/workflows/ci-meson.yml
=====================================
@@ -0,0 +1,34 @@
+name: Meson Continuous Integrations
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build-and-test:
+ strategy:
+ fail-fast: false
+ matrix:
+ cpp_compiler: [g++, clang++]
+ sanitize: [address ,undefined, thread]
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout at v4
+
+ - name: Install Meson and Boost.Test
+ run: sudo apt-get --quiet --yes install meson libboost-test-dev
+
+ - name: Setup
+ env:
+ CXX: ${{ matrix.cpp_compiler }}
+ run: meson setup build -Dwerror=true -Dwarning_level=3 -Db_sanitize=${{ matrix.sanitize }}
+
+ - name: Compile
+ run: meson compile -C build
+
+ - name: Test
+ run: meson test -C build --print-errorlogs
=====================================
.github/workflows/ci.yml
=====================================
@@ -11,11 +11,7 @@ jobs:
strategy:
matrix:
toolset: [gcc, clang]
- os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04]
- include:
- - sanitize: 1
- - os: ubuntu-20.04 # Work-around for https://bugs.launchpad.net/ubuntu/+source/gcc-10/+bug/2029910
- sanitize: 0
+ os: [ubuntu-22.04, ubuntu-24.04]
runs-on: ${{ matrix.os }}
=====================================
CONTRIBUTORS.txt
=====================================
@@ -18,3 +18,10 @@ Contributors:
- Yvan (https://github.com/max0x7ba/atomic_queue/pull/63)
- Luiz Feldmann (https://github.com/max0x7ba/atomic_queue/pull/72)
- dummyunit (https://github.com/max0x7ba/atomic_queue/pull/73)
+- NakanoMiku (https://github.com/max0x7ba/atomic_queue/pull/74)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/77)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/78)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/79)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/80)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/81)
+- Stephan Lachnit (https://github.com/max0x7ba/atomic_queue/pull/82)
=====================================
Makefile
=====================================
@@ -38,23 +38,24 @@ AR := ${ar.${TOOLSET}}
cxxflags.gcc.debug := -Og -fstack-protector-all -fno-omit-frame-pointer # -D_GLIBCXX_DEBUG
cxxflags.gcc.release := -O3 -mtune=native -ffast-math -falign-{functions,loops}=64 -DNDEBUG
cxxflags.gcc.sanitize := ${cxxflags.gcc.release} -fsanitize=thread
-cxxflags.gcc := -pthread -march=native -std=gnu++14 -W{all,extra,error,no-{maybe-uninitialized,unused-variable,unused-function,unused-local-typedefs,error=array-bounds}} -g -fmessage-length=0 ${cxxflags.gcc.${BUILD}}
+cxxflags.gcc := -std=gnu++14 -pthread -march=native -W{all,extra,error,no-{array-bounds,maybe-uninitialized,unused-variable,unused-function,unused-local-typedefs}} -fmessage-length=0 ${cxxflags.gcc.${BUILD}}
ldflags.gcc.sanitize := ${ldflags.gcc.release} -fsanitize=thread
ldflags.gcc := ${ldflags.gcc.${BUILD}}
-cflags.gcc := -pthread -march=native -W{all,extra} -g -fmessage-length=0 ${cxxflags.gcc.${BUILD}}
+cflags.gcc := -pthread -march=native -W{all,extra} -fmessage-length=0 ${cxxflags.gcc.${BUILD}}
cxxflags.clang.debug := -O0 -fstack-protector-all
cxxflags.clang.release := -O3 -mtune=native -ffast-math -falign-functions=64 -DNDEBUG
cxxflags.clang.sanitize := ${cxxflags.clang.release} -fsanitize=thread
-cxxflags.clang := -stdlib=libstdc++ -pthread -march=native -std=gnu++14 -W{all,extra,error,no-{unused-variable,unused-function,unused-local-typedefs}} -g -fmessage-length=0 ${cxxflags.clang.${BUILD}}
+cxxflags.clang := -std=gnu++14 -pthread -march=native -stdlib=libstdc++ -W{all,extra,error,no-{unused-variable,unused-function,unused-local-typedefs}} -fmessage-length=0 ${cxxflags.clang.${BUILD}}
ldflags.clang.sanitize := ${ldflags.clang.release} -fsanitize=thread
+ldflags.clang.debug := -latomic
ldflags.clang := -stdlib=libstdc++ ${ldflags.clang.${BUILD}}
# Additional CPPFLAGS, CXXFLAGS, CFLAGS, LDLIBS, LDFLAGS can come from the command line, e.g. make CPPFLAGS='-I<my-include-dir>', or from environment variables.
-cxxflags := ${cxxflags.${TOOLSET}} ${CXXFLAGS}
-cflags := ${cflags.${TOOLSET}} ${CFLAGS}
-cppflags := ${CPPFLAGS} -Iinclude
+cxxflags := ${cxxflags.${TOOLSET}} -g ${CXXFLAGS}
+cflags := ${cflags.${TOOLSET}} -g ${CFLAGS}
+cppflags := -Iinclude ${CPPFLAGS}
ldflags := -fuse-ld=gold -pthread -g ${ldflags.${TOOLSET}} ${LDFLAGS}
ldlibs := -lrt ${LDLIBS}
@@ -65,14 +66,13 @@ cppflags.moodycamel := -I$(abspath ..)
ldlibs.moodycamel :=
cppflags.xenium := -I${abspath ../xenium}
+cxxflags.xenium := -std=gnu++17
ldlibs.xenium :=
recompile := ${build_dir}/.make/recompile
relink := ${build_dir}/.make/relink
COMPILE.CXX = ${CXX} -o $@ -c ${cppflags} ${cxxflags} -MD -MP $(abspath $<)
-COMPILE.S = ${CXX} -o- -S -fverbose-asm -masm=intel ${cppflags} ${cxxflags} $(abspath $<) | c++filt | egrep -v '^[[:space:]]*\.(loc|cfi|L[A-Z])' > $@
-PREPROCESS.CXX = ${CXX} -o $@ -E ${cppflags} ${cxxflags} $(abspath $<)
COMPILE.C = ${CC} -o $@ -c ${cppflags} ${cflags} -MD -MP $(abspath $<)
LINK.EXE = ${LD} -o $@ $(ldflags) $(filter-out ${relink},$^) $(ldlibs)
LINK.SO = ${LD} -o $@ -shared $(ldflags) $(filter-out ${relink},$^) $(ldlibs)
@@ -86,15 +86,17 @@ else
strip2 = $(strip ${1})
endif
+#
+# Build targets definitions begin.
+#
+
exes := benchmarks tests example
all : ${exes}
-${exes} : % : ${build_dir}/%
- ln -sf ${<:${CURDIR}/%=%}
-
benchmarks_src := benchmarks.cc cpu_base_frequency.cc huge_pages.cc
${build_dir}/benchmarks : cppflags += ${cppflags.tbb} ${cppflags.moodycamel} ${cppflags.xenium}
+${build_dir}/benchmarks : cxxflags += ${cxxflags.tbb} ${cxxflags.moodycamel} ${cxxflags.xenium}
${build_dir}/benchmarks : ldlibs += ${ldlibs.tbb} ${ldlibs.moodycamel} ${ldlibs.xenium} -ldl
${build_dir}/benchmarks : ${benchmarks_src:%.cc=${build_dir}/%.o} ${relink} | ${build_dir}
$(call strip2,${LINK.EXE})
@@ -112,6 +114,13 @@ ${build_dir}/example : ${example_src:%.cc=${build_dir}/%.o} ${relink} | ${build_
$(call strip2,${LINK.EXE})
-include ${example_src:%.cc=${build_dir}/%.d}
+#
+# Build targets definitions end.
+#
+
+${exes} : % : ${build_dir}/%
+ ln -sf ${<:${CURDIR}/%=%}
+
${build_dir}/%.so : cxxflags += -fPIC
${build_dir}/%.so : ${relink} | ${build_dir}
$(call strip2,${LINK.SO})
@@ -125,14 +134,6 @@ ${build_dir}/%.o : src/%.cc ${recompile} | ${build_dir}
${build_dir}/%.o : src/%.c ${recompile} | ${build_dir}
$(call strip2,${COMPILE.C})
-${build_dir}/%.S : cppflags += ${cppflags.tbb} ${cppflags.moodycamel} ${cppflags.xenium}
-${build_dir}/%.S : src/%.cc ${recompile} | ${build_dir}
- $(call strip2,${COMPILE.S})
-
-${build_dir}/%.I : cppflags += ${cppflags.tbb} ${cppflags.moodycamel} ${cppflags.xenium}
-${build_dir}/%.I : src/%.cc ${recompile} | ${build_dir}
- $(call strip2,${PREPROCESS.CXX})
-
${build_dir}/%.d : ;
${build_dir}/.make : | ${build_dir}
@@ -141,7 +142,7 @@ ${build_dir} ${build_dir}/.make:
ver = "$(shell ${1} --version | head -n1)"
# Trigger recompilation when compiler environment change.
-env.compile := $(call ver,${CXX}) ${cppflags} ${cxxflags} ${cppflags.tbb} ${cppflags.moodycamel} ${cppflags.xenium}
+env.compile := $(call ver,${CXX}) ${cppflags} ${cxxflags} ${cppflags.tbb} ${cppflags.moodycamel} ${cppflags.xenium} ${cxxflags.tbb} ${cxxflags.moodycamel} ${cxxflags.xenium}
# Trigger relink when linker environment change.
env.link := $(call ver,${LD}) ${ldflags} ${ldlibs} ${ldlibs.tbb} ${ldlibs.moodycamel} ${ldlibs.xenium}
@@ -174,7 +175,7 @@ rtags :
${MAKE} --always-make --just-print all | { rtags-rc -c -; true; }
clean :
- rm -rf ${build_dir} ${exes}
+ rm -rf ${exes} ${build_dir}
versions:
${MAKE} --version | awk 'FNR<2'
@@ -184,3 +185,10 @@ env :
env | sort --ignore-case
.PHONY : update_env_txt env versions rtags run_benchmarks clean all run_%
+.DELETE_ON_ERROR:
+.SECONDARY:
+.SUFFIXES:
+
+# Local Variables:
+# compile-command: "/bin/time make -rC ~/src/atomic_queue -j$(($(nproc)/2)) BUILD=debug run_tests"
+# End:
=====================================
README.md
=====================================
@@ -7,6 +7,7 @@
<br>
[](https://github.com/max0x7ba/atomic_queue/actions/workflows/ci.yml)
[](https://github.com/max0x7ba/atomic_queue/actions/workflows/cmake-gcc-clang.yml)
+[](https://github.com/max0x7ba/atomic_queue/actions/workflows/ci-meson.yml)
<br>


@@ -15,13 +16,17 @@

# atomic_queue
-C++14 multiple-producer-multiple-consumer *lock-free* queues based on circular buffer and [`std::atomic`][3]. Designed with a goal to minimize the latency between one thread pushing an element into a queue and another thread popping it from the queue.
+C++14 multiple-producer-multiple-consumer *lock-free* queues based on circular buffers and [`std::atomic`][3].
-It has been developed, tested and benchmarked on Linux, but should support any C++14 platforms which implement `std::atomic`. Reported as compatible with Windows, but the continuous integrations hosted by GitHub are currently set up only for x86_64 platform on Ubuntu-20.04 and Ubuntu-22.04. Pull requests to extend the [continuous integrations][18] to run on other architectures and/or platforms are welcome.
+Designed with a goal to minimize the latency between one thread pushing an element into a queue and another thread popping it from the queue.
+
+It has been developed, tested and benchmarked on Linux, but should support any C++14 platforms which implement `std::atomic`. Reported as compatible with Windows, but the continuous integrations hosted by GitHub are currently set up only for x86_64 platform on Ubuntu-22.04 and Ubuntu-24.04. Pull requests to extend the [continuous integrations][18] to run on other architectures and/or platforms are welcome.
## Design Principles
When minimizing latency a good design is not when there is nothing left to add, but rather when there is nothing left to remove, as these queues exemplify.
+Minimizing latency naturally maximizes throughput. Low latency reciprocal is high throuhput, in ideal mathematical and practical engineering sense. Low latency is incompatible with any delays and/or batching, which destroy original (hardware) global time order of events pushed into one queue by different threads. Maximizing throughput, on the other hand, can be done at expense of latency by delaying and batching multiple updates.
+
The main design principle these queues follow is _minimalism_, which results in such design choices as:
* Bare minimum of atomic instructions. Inlinable by default push and pop functions can hardly be any cheaper in terms of CPU instruction number / L1i cache pressure.
@@ -38,20 +43,6 @@ These design choices are also limitations:
Ultra-low-latency applications need just that and nothing more. The minimalism pays off, see the [throughput and latency benchmarks][1].
-Available containers are:
-* `AtomicQueue` - a fixed size ring-buffer for atomic elements.
-* `OptimistAtomicQueue` - a faster fixed size ring-buffer for atomic elements which busy-waits when empty or full. It is `AtomicQueue` used with `push`/`pop` instead of `try_push`/`try_pop`.
-* `AtomicQueue2` - a fixed size ring-buffer for non-atomic elements.
-* `OptimistAtomicQueue2` - a faster fixed size ring-buffer for non-atomic elements which busy-waits when empty or full. It is `AtomicQueue2` used with `push`/`pop` instead of `try_push`/`try_pop`.
-
-These containers have corresponding `AtomicQueueB`, `OptimistAtomicQueueB`, `AtomicQueueB2`, `OptimistAtomicQueueB2` versions where the buffer size is specified as an argument to the constructor.
-
-Totally ordered mode is supported. In this mode consumers receive messages in the same FIFO order the messages were posted. This mode is supported for `push` and `pop` functions, but for not the `try_` versions. On Intel x86 the totally ordered mode has 0 cost, as of 2019.
-
-Single-producer-single-consumer mode is supported. In this mode, no expensive atomic read-modify-write CPU instructions are necessary, only the cheapest atomic loads and stores. That improves queue throughput significantly.
-
-Move-only queue element types are fully supported. For example, a queue of `std::unique_ptr<T>` elements would be `AtomicQueue2B<std::unique_ptr<T>>` or `AtomicQueue2<std::unique_ptr<T>, CAPACITY>`.
-
## Role Models
Several other well established and popular thread-safe containers are used for reference in the [benchmarks][1]:
* `std::mutex` - a fixed size ring-buffer with `std::mutex`.
@@ -102,7 +93,30 @@ make -r -j4 run_benchmarks
The benchmark also requires Intel TBB library to be available. It assumes that it is installed in `/usr/local/include` and `/usr/local/lib`. If it is installed elsewhere you may like to modify `cppflags.tbb` and `ldlibs.tbb` in `Makefile`.
-# API
+# Library contents
+## Available queues
+* `AtomicQueue` - a fixed size ring-buffer for atomic elements.
+* `OptimistAtomicQueue` - a faster fixed size ring-buffer for atomic elements which busy-waits when empty or full. It is `AtomicQueue` used with `push`/`pop` instead of `try_push`/`try_pop`.
+* `AtomicQueue2` - a fixed size ring-buffer for non-atomic elements.
+* `OptimistAtomicQueue2` - a faster fixed size ring-buffer for non-atomic elements which busy-waits when empty or full. It is `AtomicQueue2` used with `push`/`pop` instead of `try_push`/`try_pop`.
+
+These containers have corresponding `AtomicQueueB`, `OptimistAtomicQueueB`, `AtomicQueueB2`, `OptimistAtomicQueueB2` versions where the buffer size is specified as an argument to the constructor.
+
+Totally ordered mode is supported. In this mode consumers receive messages in the same FIFO order the messages were posted. This mode is supported for `push` and `pop` functions, but for not the `try_` versions. On Intel x86 the totally ordered mode has 0 cost, as of 2019.
+
+Single-producer-single-consumer mode is supported. In this mode, no expensive atomic read-modify-write CPU instructions are necessary, only the cheapest atomic loads and stores. That improves queue throughput significantly.
+
+Move-only queue element types are fully supported. For example, a queue of `std::unique_ptr<T>` elements would be `AtomicQueue2B<std::unique_ptr<T>>` or `AtomicQueue2<std::unique_ptr<T>, CAPACITY>`.
+
+## Queue schematics
+
+```
+queue-end queue-front
+[newest-element, ..., oldest-element]
+push() pop()
+```
+
+## Queue API
The queue class templates provide the following member functions:
* `try_push` - Appends an element to the end of the queue. Returns `false` when the queue is full.
* `try_pop` - Removes an element from the front of the queue. Returns `false` when the queue is empty.
@@ -121,15 +135,13 @@ Note that _optimism_ is a choice of a queue modification operation control flow,
See [example.cc](src/example.cc) for a usage example.
-TODO: full API reference.
-
+# Implementation Notes
## Memory order of non-atomic loads and stores
`push` and `try_push` operations _synchronize-with_ (as defined in [`std::memory_order`][17]) with any subsequent `pop` or `try_pop` operation of the same queue object. Meaning that:
* No non-atomic load/store gets reordered past `push`/`try_push`, which is a `memory_order::release` operation. Same memory order as that of `std::mutex::unlock`.
* No non-atomic load/store gets reordered prior to `pop`/`try_pop`, which is a `memory_order::acquire` operation. Same memory order as that of `std::mutex::lock`.
* The effects of a producer thread's non-atomic stores followed by `push`/`try_push` of an element into a queue become visible in the consumer's thread which `pop`/`try_pop` that particular element.
-# Implementation Notes
## Ring-buffer capacity
The available queues here use a ring-buffer array for storing elements. The capacity of the queue is fixed at compile time or construction time.
@@ -190,6 +202,8 @@ There are a few OS behaviours that complicate benchmarking:
* Real-time thread throttling disabled.
* Adverse address space randomisation may cause extra CPU cache conflicts, as well as other processes running on the system. To minimise effects of that `benchmarks` executable is run at least 33 times. The benchmark charts display average values. The chart tooltip also displays the standard deviation, minimum and maximum values.
+Benchmark performance of single-producer-single-consumer queues `boost::lockfree::spsc_queue`, `moodycamel::ReaderWriterQueue` and these queues in single-producer-single-consumer mode should be identical because they implement exactly the same algorithm using exactly the same atomic load and store instructions. `boost::lockfree::spsc_queue` implementation benchmarked at that time had no optimizations for minimizing L1d cache contention, cold branch misprediction or pipeline stalls from subtler issues noticable only in the generated assembly code.
+
I only have access to a few x86-64 machines. If you have access to different hardware feel free to submit the output file of `scripts/run-benchmarks.sh` and I will include your results into the benchmarks page.
### Huge pages
@@ -216,7 +230,7 @@ One thread posts an integer to another thread through one queue and waits for a
Contributions are more than welcome. `.editorconfig` and `.clang-format` can be used to automatically match code formatting.
# Reading material
-Some books on the subject of multi-threaded programming I found instructive:
+Some books on the subject of multi-threaded programming I found quite instructive:
* _Programming with POSIX Threads_ by David R. Butenhof.
* _The Art of Multiprocessor Programming_ by Maurice Herlihy, Nir Shavit.
=====================================
include/atomic_queue/atomic_queue.h
=====================================
@@ -334,7 +334,7 @@ public:
}
bool was_full() const noexcept {
- return was_size() >= static_cast<int>(static_cast<Derived const&>(*this).size_);
+ return was_size() >= capacity();
}
unsigned was_size() const noexcept {
=====================================
include/atomic_queue/defs.h
=====================================
@@ -56,6 +56,14 @@ static inline void spin_loop_pause() noexcept {
asm volatile (".insn i 0x0F, 0, x0, x0, 0x010");
}
} // namespace atomic_queue
+#elif defined(__loongarch__)
+namespace atomic_queue {
+constexpr int CACHE_LINE_SIZE = 64;
+static inline void spin_loop_pause() noexcept
+{
+ asm volatile("nop \n nop \n nop \n nop \n nop \n nop \n nop \n nop");
+}
+} // namespace atomic_queue
#else
#ifdef _MSC_VER
#pragma message("Unknown CPU architecture. Using L1 cache line size of 64 bytes and no spinloop pause instruction.")
=====================================
meson.build
=====================================
@@ -1,6 +1,6 @@
# Copyright (c) 2019 Maxim Egorushkin. MIT License. See the full licence in file LICENSE.
-# (rm -rf build; meson build; cd build; time ninja -v)
+# (rm -rf build; meson setup build; time ninja -C build -v)
project(
'atomic_queue', 'cpp',
@@ -8,35 +8,63 @@ project(
default_options : ['cpp_std=gnu++14', 'buildtype=release', 'b_ndebug=if-release']
)
-cxx = meson.get_compiler('cpp')
-dl = cxx.find_library('dl', required : true)
-threads = dependency('threads')
-unit_test_framework = dependency('boost', modules : ['unit_test_framework'])
-if get_option('benchmarks')
- tbb = cxx.find_library('tbb', required : true)
- xenium = declare_dependency(include_directories : '../xenium')
- moodycamel = declare_dependency(include_directories : '../')
-endif
+threads_dep = dependency('threads')
-atomic_queue = declare_dependency(include_directories : ['include'], dependencies : threads)
+atomic_queue_dep = declare_dependency(include_directories : ['include'], dependencies : threads_dep)
-tests_exe = executable(
- 'tests',
- 'src/tests.cc',
- dependencies : [atomic_queue, unit_test_framework]
-)
-test('tests', tests_exe)
+if get_option('tests')
+ unit_test_framework_dep = dependency('boost', modules : ['unit_test_framework'])
-example_exe = executable(
- 'example',
- 'src/example.cc',
- dependencies : [atomic_queue]
-)
+ tests_exe = executable(
+ 'tests',
+ 'src/tests.cc',
+ dependencies : [atomic_queue_dep, unit_test_framework_dep],
+ )
+ test('tests', tests_exe)
+
+ example_exe = executable(
+ 'example',
+ 'src/example.cc',
+ dependencies : [atomic_queue_dep],
+ )
+ test('example', example_exe)
+endif
if get_option('benchmarks')
+ incompatible_cpp_std = ['c++98', 'c++03', 'c++11', 'c++14', 'gnu++03', 'gnu++11', 'gnu++14', 'vc++14']
+ if incompatible_cpp_std.contains(get_option('cpp_std'))
+ error('Benchmarks require C++17 or higher')
+ endif
+
+ cxx = meson.get_compiler('cpp')
+ dl_dep = cxx.find_library('dl')
+ xenium_dep = declare_dependency(include_directories : '../xenium')
+ boost_dep = dependency('boost')
+ tbb_dep = cxx.find_library('tbb')
+ moodycamel_dep = declare_dependency(include_directories : '../')
+
benchmarks_exe = executable(
'benchmarks',
['src/benchmarks.cc', 'src/cpu_base_frequency.cc', 'src/huge_pages.cc'],
- dependencies : [atomic_queue, xenium, moodycamel, tbb, dl]
+ include_directories : ['src'],
+ dependencies : [atomic_queue_dep, dl_dep, xenium_dep, boost_dep, tbb_dep, moodycamel_dep],
)
+ benchmark('benchmarks', benchmarks_exe)
endif
+
+install_headers(
+ files(
+ 'include/atomic_queue/atomic_queue.h',
+ 'include/atomic_queue/atomic_queue_mutex.h',
+ 'include/atomic_queue/barrier.h',
+ 'include/atomic_queue/defs.h',
+ 'include/atomic_queue/spinlock.h',
+ ),
+ subdir: 'atomic_queue'
+)
+pkg = import('pkgconfig')
+pkg.generate(
+ name: 'atomic_queue',
+ description: 'C++14 multiple-producer-multiple-consumer lock-free queues based on circular buffers',
+ libraries: [threads_dep]
+)
=====================================
meson_options.txt
=====================================
@@ -1,2 +1,4 @@
-option('benchmarks', type : 'boolean', value : true,
- description : 'Do not build benchmarks; ignore their dependencies')
+option('benchmarks', type : 'boolean', value : false,
+ description : 'Build benchmarks (requires Boost, TBB, Xenium, moodycamel and C++17)')
+option('tests', type : 'boolean', value : true,
+ description : 'Build tests and example (requires Boost)')
=====================================
src/tests.cc
=====================================
@@ -6,7 +6,6 @@
#include <boost/test/unit_test.hpp>
#include "atomic_queue/atomic_queue.h"
-#include "atomic_queue/atomic_queue_mutex.h"
#include "atomic_queue/barrier.h"
#include <cstdint>
@@ -250,6 +249,8 @@ BOOST_AUTO_TEST_CASE(try_push) {
BOOST_AUTO_TEST_CASE(size) {
atomic_queue::RetryDecorator<atomic_queue::AtomicQueueB2<float>> q(10);
BOOST_CHECK_EQUAL(q.capacity(), CACHE_LINE_SIZE * CACHE_LINE_SIZE);
+ BOOST_CHECK(q.was_empty());
+ BOOST_CHECK(!q.was_full());
}
BOOST_AUTO_TEST_CASE(power_of_2) {
View it on GitLab: https://salsa.debian.org/med-team/libatomic-queue/-/commit/f2b7705efe38224d4647010c3014127c3b471f3b
--
View it on GitLab: https://salsa.debian.org/med-team/libatomic-queue/-/commit/f2b7705efe38224d4647010c3014127c3b471f3b
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20250624/663a1d85/attachment-0001.htm>
More information about the debian-med-commit
mailing list