From b7a005b6e4e02397484892e41bb3a6ec828b5e07 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Tue, 12 Sep 2023 14:24:37 +0200 Subject: [PATCH 01/10] some ref for stack --- lockfree/stack/hazard/hp.h | 28 ++++++++++++++++++++ lockfree/stack/hazard/hp_owner.h | 28 +++++--------------- lockfree/stack/hazard/reclaim.h | 30 ++++++++++----------- lockfree/stack/hazard/stack.h | 45 ++++++++++++++++++-------------- main.cpp | 6 ----- 5 files changed, 74 insertions(+), 63 deletions(-) create mode 100644 lockfree/stack/hazard/hp.h delete mode 100644 main.cpp diff --git a/lockfree/stack/hazard/hp.h b/lockfree/stack/hazard/hp.h new file mode 100644 index 0000000..a4e8bf3 --- /dev/null +++ b/lockfree/stack/hazard/hp.h @@ -0,0 +1,28 @@ +// +// Created by focus on 9/12/23. +// + +#pragma once + +#include +#include +#include +#include + +namespace sync_cpp { + +static constexpr size_t MaxHazardPointers = 100; + +struct HazardPtr { + std::atomic id; + std::atomic ptr; +}; + +HazardPtr hazard_ptrs[MaxHazardPointers]; + +template +void do_delete(void *p) { + delete static_cast(p); +} + +} // namespace sync_cpp \ No newline at end of file diff --git a/lockfree/stack/hazard/hp_owner.h b/lockfree/stack/hazard/hp_owner.h index 324e5ca..cfa4f9e 100644 --- a/lockfree/stack/hazard/hp_owner.h +++ b/lockfree/stack/hazard/hp_owner.h @@ -5,30 +5,20 @@ #include #include -namespace sync_cpp { - -static constexpr size_t MaxHazardPointers = 100; -struct HazardPtr -{ - std::atomic id; - std::atomic ptr; -}; - -HazardPtr hazard_ptrs[MaxHazardPointers]; +#include "hp.h" -template -void do_delete(void* p) { - delete static_cast(p); -} +namespace sync_cpp { class hp_owner { + HazardPtr* hp; + public: hp_owner() : hp(nullptr) { - for(size_t i=0; iptr.store(nullptr); hp->id.store(std::this_thread::get_id()); } - - - private: - HazardPtr* hp; }; diff --git a/lockfree/stack/hazard/reclaim.h b/lockfree/stack/hazard/reclaim.h index f0f49b6..8ace9bc 100644 --- a/lockfree/stack/hazard/reclaim.h +++ b/lockfree/stack/hazard/reclaim.h @@ -2,6 +2,7 @@ #include #include +#include #include "hp_owner.h" @@ -14,7 +15,7 @@ struct Reclaim { data_to_reclaim* next; template - data_to_reclaim(T* p): + explicit data_to_reclaim(T* p): data(p), deleter(&do_delete), next(nullptr) @@ -25,43 +26,40 @@ struct Reclaim { } }; - std::atomic nodes_to_reclame_; + std::atomic nodes_to_reclaim_; - void add_to_reclame_list(data_to_reclaim* node) { - node->next = nodes_to_reclame_.load(); - while(!nodes_to_reclame_.compare_exchange_weak(node->next, node)) {} + void add_to_reclaim_list(data_to_reclaim* node) { + node->next = nodes_to_reclaim_.load(); + while(!nodes_to_reclaim_.compare_exchange_weak(node->next, node)) {} } template void reclaim_later(T* data) { - add_to_reclame_list(new data_to_reclaim(data)); + add_to_reclaim_list(new data_to_reclaim(data)); } void delete_nodes_with_no_hazard() { - data_to_reclaim* current = nodes_to_reclame_.exchange(nullptr); + data_to_reclaim* current = nodes_to_reclaim_.exchange(nullptr); while (current) { data_to_reclaim* next = current->next; if (!OutstandingHazardPtrsFor(current->data)) { delete current; } else { - add_to_reclame_list(current); + add_to_reclaim_list(current); } current = next; } } - bool OutstandingHazardPtrsFor(void* p) { - for(size_t i=0; i& GetHazardPtrForCurrentThread() { + static std::atomic& GetHazardPtrForCurrentThread() { thread_local static hp_owner hazard; return hazard.get_pointer(); } diff --git a/lockfree/stack/hazard/stack.h b/lockfree/stack/hazard/stack.h index 579ad95..1e55157 100644 --- a/lockfree/stack/hazard/stack.h +++ b/lockfree/stack/hazard/stack.h @@ -17,31 +17,39 @@ class LockFreeStackHazard final : private Reclaim { Node* next; }; + std::atomic head_; + + Node* DropHead() { + std::atomic& hp = GetHazardPtrForCurrentThread(); + Node* old_head = head_.load(); + do { + Node* temp; + do { + temp = old_head; + hp.store(old_head); + old_head = head_.load(); + } while (old_head != temp); + // hp sets to head + + } while (old_head && !head_.compare_exchange_strong(old_head, old_head->next)); + + // clean hp + hp.store(nullptr); + + return old_head; + } + public: void Push(T data) { Node* node = new Node{ - std::make_shared(std::move(data)), - nullptr + .data=std::make_shared(std::move(data)), + .next=nullptr }; while(!head_.compare_exchange_weak(node->next, node)) {} } std::shared_ptr TryPop() { - std::atomic& hp = GetHazardPtrForCurrentThread(); - Node* old_head = head_.load(); - do { - Node* temp; - do { - temp = old_head; - hp.store(old_head); - old_head = head_.load(); - } while (old_head != temp); - // hp sets to head - - } while (old_head && !head_.compare_exchange_strong(old_head, old_head->next)); - - // clean hp - hp.store(nullptr); + Node* old_head = DropHead(); std::shared_ptr res; if (old_head) { @@ -59,9 +67,6 @@ class LockFreeStackHazard final : private Reclaim { ~LockFreeStackHazard() { while(TryPop()) {} } - - private: - std::atomic head_; }; } // namespace sync_cpp \ No newline at end of file diff --git a/main.cpp b/main.cpp deleted file mode 100644 index 8fbfc65..0000000 --- a/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main() { - std::cout << "Hello, World!" << std::endl; - return 0; -} From 68c8efb1f8406d7dbefb5846204d049d18797a1b Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Tue, 12 Sep 2023 15:53:12 +0200 Subject: [PATCH 02/10] check idea --- lockfree/stack/hazard/stack.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lockfree/stack/hazard/stack.h b/lockfree/stack/hazard/stack.h index 1e55157..b182216 100644 --- a/lockfree/stack/hazard/stack.h +++ b/lockfree/stack/hazard/stack.h @@ -54,12 +54,12 @@ class LockFreeStackHazard final : private Reclaim { std::shared_ptr res; if (old_head) { res.swap(old_head->data); - if (OutstandingHazardPtrsFor(old_head)) { - reclaim_later(old_head); - } else { - delete old_head; - } - delete_nodes_with_no_hazard(); +// if (OutstandingHazardPtrsFor(old_head)) { +// reclaim_later(old_head); +// } else { +// delete old_head; +// } +// delete_nodes_with_no_hazard(); } return res; } From ad7903ec355d3d8f80a3079b25d1aa92061aae56 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Tue, 12 Sep 2023 16:34:21 +0200 Subject: [PATCH 03/10] check idea --- lockfree/stack/hazard/stack.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lockfree/stack/hazard/stack.h b/lockfree/stack/hazard/stack.h index b182216..1e55157 100644 --- a/lockfree/stack/hazard/stack.h +++ b/lockfree/stack/hazard/stack.h @@ -54,12 +54,12 @@ class LockFreeStackHazard final : private Reclaim { std::shared_ptr res; if (old_head) { res.swap(old_head->data); -// if (OutstandingHazardPtrsFor(old_head)) { -// reclaim_later(old_head); -// } else { -// delete old_head; -// } -// delete_nodes_with_no_hazard(); + if (OutstandingHazardPtrsFor(old_head)) { + reclaim_later(old_head); + } else { + delete old_head; + } + delete_nodes_with_no_hazard(); } return res; } From ac0b0826a4c7b584ea1c442fc765eb06aee9efc5 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Wed, 13 Sep 2023 23:30:56 +0200 Subject: [PATCH 04/10] add spsc queue --- lockfree/CMakeLists.txt | 3 +- lockfree/queue/spsc/CMakeLists.txt | 18 +++++++ lockfree/queue/spsc/queue.h | 61 +++++++++++++++++++++++ lockfree/queue/spsc/test/CMakeLists.txt | 20 ++++++++ lockfree/queue/spsc/test/main.cpp | 11 +++++ lockfree/queue/spsc/test/unit-tests.cpp | 66 +++++++++++++++++++++++++ 6 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 lockfree/queue/spsc/CMakeLists.txt create mode 100644 lockfree/queue/spsc/queue.h create mode 100644 lockfree/queue/spsc/test/CMakeLists.txt create mode 100644 lockfree/queue/spsc/test/main.cpp create mode 100644 lockfree/queue/spsc/test/unit-tests.cpp diff --git a/lockfree/CMakeLists.txt b/lockfree/CMakeLists.txt index a4c631b..89fa72c 100644 --- a/lockfree/CMakeLists.txt +++ b/lockfree/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.25) add_subdirectory(stack/counting) -add_subdirectory(stack/hazard) \ No newline at end of file +add_subdirectory(stack/hazard) +add_subdirectory(queue/spsc) diff --git a/lockfree/queue/spsc/CMakeLists.txt b/lockfree/queue/spsc/CMakeLists.txt new file mode 100644 index 0000000..ba904b4 --- /dev/null +++ b/lockfree/queue/spsc/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.25) + +include_directories(.) +add_library(queue_spsc + queue.h +) + +target_link_libraries(queue_spsc + atomic + project_sanitizers + project_warnings +) + +target_include_directories(queue_spsc PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") + +set_target_properties(queue_spsc PROPERTIES LINKER_LANGUAGE CXX) + +add_subdirectory(test) \ No newline at end of file diff --git a/lockfree/queue/spsc/queue.h b/lockfree/queue/spsc/queue.h new file mode 100644 index 0000000..55c40bf --- /dev/null +++ b/lockfree/queue/spsc/queue.h @@ -0,0 +1,61 @@ +// +// Created by focus on 9/13/23. +// + +#include +#include + + +namespace sync_cpp { + +template +class SPSCQueue final { + struct Node final { + std::shared_ptr data; + Node* next; + }; + + std::atomic head_; + std::atomic tail_; + + Node* pop_head() { + Node* const old_head = head_.load(); + if (old_head == tail_.load()) { + return nullptr; + } + head_.store(old_head->next); + return old_head; + } + +public: + SPSCQueue() : head_(new Node), tail_(head_.load()) + {} + + SPSCQueue(const SPSCQueue&) = delete; + SPSCQueue(SPSCQueue&&) noexcept = delete; + ~SPSCQueue() { + while (pop() != nullptr); + } + + void push(T new_value) { + auto new_data = std::make_shared(std::move(new_value)); + Node* p = new Node(); + Node* const old_tail = tail_.load(); + old_tail->data.swap(new_data); + old_tail->next = p; + tail_.store(p); + } + + std::shared_ptr pop() { + Node* old_head = pop_head(); + if (!old_head) { + return std::shared_ptr(); + } + + std::shared_ptr res(old_head->data); + delete old_head; + return res; + } +}; + +} // namespace sync_cpp diff --git a/lockfree/queue/spsc/test/CMakeLists.txt b/lockfree/queue/spsc/test/CMakeLists.txt new file mode 100644 index 0000000..2826795 --- /dev/null +++ b/lockfree/queue/spsc/test/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.25) + +include_directories(${CONAN_INCLUDE_DIRS_GTEST}) +include_directories(${CONAN_INCLUDE_DIRS_BENCHMARK}) + +set(TEST_APP_NAME unit_test_queue_spsc) + +add_executable(${TEST_APP_NAME} + main.cpp + unit-tests.cpp +) + +target_link_libraries(${TEST_APP_NAME} + queue_spsc + ${CONAN_LIBS_GTEST} + project_sanitizers + project_warnings +) + +enable_testing() \ No newline at end of file diff --git a/lockfree/queue/spsc/test/main.cpp b/lockfree/queue/spsc/test/main.cpp new file mode 100644 index 0000000..478d0a4 --- /dev/null +++ b/lockfree/queue/spsc/test/main.cpp @@ -0,0 +1,11 @@ +// +// Created by focus on 9/13/23. +// + +#include "gtest/gtest.h" + +int +main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/lockfree/queue/spsc/test/unit-tests.cpp b/lockfree/queue/spsc/test/unit-tests.cpp new file mode 100644 index 0000000..927e5d4 --- /dev/null +++ b/lockfree/queue/spsc/test/unit-tests.cpp @@ -0,0 +1,66 @@ +// +// Created by focus on 9/13/23. +// + +#include "gtest/gtest.h" + +#include + +#include + +class TestSPSCQueue : public ::testing::Test { +public: +}; + +TEST_F(TestSPSCQueue, push_pop) { + sync_cpp::SPSCQueue q; + + q.push(117); + auto item = q.pop(); + ASSERT_TRUE(item); + ASSERT_EQ(*item, 117); + + auto empty = q.pop(); + ASSERT_FALSE(empty); +} + +TEST_F(TestSPSCQueue, only_pop) { + sync_cpp::SPSCQueue stack; + + auto empty = stack.pop(); + ASSERT_FALSE(empty); + + empty = stack.pop(); + ASSERT_FALSE(empty); +} + +TEST_F(TestSPSCQueue, 2_threads) { + sync_cpp::SPSCQueue q; + + auto th1 = std::jthread([&] { + for (size_t i=0; i<20'000; i++) { + q.push(i); + } + }); + + std::vector result; + result.reserve(20'000); + size_t counter = 0; + while(true) { + auto data = q.pop(); + if (!data) { + continue; + } + counter++; + result.push_back(*data); + if (counter == 20'000) { + break; + } + } + + std::sort(result.begin(), result.end()); + + for(size_t i=0; i<20'000; i++) { + ASSERT_EQ(result[i], i); + } +} \ No newline at end of file From d8c1b16fbb1726031ade8afa4a2d61b782981c4c Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Wed, 13 Sep 2023 23:34:23 +0200 Subject: [PATCH 05/10] up CI --- .github/workflows/cmake.yaml | 18 ++++--- .github/workflows/queue_spsc.yaml | 87 +++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/queue_spsc.yaml diff --git a/.github/workflows/cmake.yaml b/.github/workflows/cmake.yaml index a6a9ee3..41dafee 100644 --- a/.github/workflows/cmake.yaml +++ b/.github/workflows/cmake.yaml @@ -4,11 +4,13 @@ on: push: jobs: - lockfree_stack_counting: - uses: ./.github/workflows/stack_counting.yaml - lockfree_stack_hazard: - uses: ./.github/workflows/stack_hazard_ptr.yaml - spinlock: - uses: ./.github/workflows/spinlock.yaml - mutex: - uses: ./.github/workflows/mutex.yaml \ No newline at end of file +# lockfree_stack_counting: +# uses: ./.github/workflows/stack_counting.yaml +# lockfree_stack_hazard: +# uses: ./.github/workflows/stack_hazard_ptr.yaml +# spinlock: +# uses: ./.github/workflows/spinlock.yaml +# mutex: +# uses: ./.github/workflows/mutex.yaml + queue_spsc: + uses: ./.github/workflows/queue_spsc.yaml \ No newline at end of file diff --git a/.github/workflows/queue_spsc.yaml b/.github/workflows/queue_spsc.yaml new file mode 100644 index 0000000..754186e --- /dev/null +++ b/.github/workflows/queue_spsc.yaml @@ -0,0 +1,87 @@ +name: Cmake + +on: + workflow_call: + +env: + BUILD_TYPE_DEBUG: Debug + BUILD_TYPE_RELEASE: Release + + CLANG_15: clang++-15 + +jobs: + ubuntu-clang-15-debug-address-leak-undefined-sanitize: + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install Dependencies + uses: actions/cache@v2 + with: + path: ~/.conan/data + key: ${{ runner.os }}-conan-${{ hashFiles('conanfile.txt') }}-queue-spsc-address + - run: | + export BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} + ./tools/install_deps.sh + - run: | + mkdir -p ${{github.workspace}}/build + cmake -B ${{github.workspace}}/build -DCMAKE_CXX_COMPILER=/bin/${{env.CLANG_15}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} \ + -DCHECK_SANITIZE=ON -DENABLE_SANITIZER_ADDRESS=True -DENABLE_SANITIZER_LEAK=True -DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=True + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target queue_spsc -- -j 2 + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target unit_test_queue_spsc -- -j 2 + - run: ${{github.workspace}}/build/bin/unit_test_queue_spsc + --gtest_shuffle + --gtest_color=yes + + ubuntu-clang-15-debug-thread-sanitize: + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install Dependencies + uses: actions/cache@v2 + with: + path: ~/.conan/data + key: ${{ runner.os }}-conan-${{ hashFiles('conanfile.txt') }}-queue-spsc-thread + - run: | + export BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} + ./tools/install_deps.sh + - run: | + mkdir -p ${{github.workspace}}/build + cmake -B ${{github.workspace}}/build -DCMAKE_CXX_COMPILER=/bin/${{env.CLANG_15}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} \ + -DCHECK_SANITIZE=ON -DENABLE_SANITIZER_THREAD=True + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target queue_spsc -- -j 2 + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target unit_test_queue_spsc -- -j 2 + - run: ${{github.workspace}}/build/bin/unit_test_queue_spsc + --gtest_shuffle + --gtest_color=yes + + ubuntu-clang-15-release: + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install Dependencies + uses: actions/cache@v2 + with: + path: ~/.conan/data + key: ${{ runner.os }}-conan-${{ hashFiles('conanfile.txt') }}-queue-spsc-release + - run: | + export BUILD_TYPE=${{env.BUILD_TYPE_RELEASE}} + ./tools/install_deps.sh + - run: | + mkdir -p ${{github.workspace}}/build + cmake -B ${{github.workspace}}/build -DCMAKE_CXX_COMPILER=/bin/${{env.CLANG_15}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE_RELEASE}} + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_RELEASE}} --target queue_spsc -- -j 2 + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_RELEASE}} --target unit_test_queue_spsc -- -j 2 +# cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_RELEASE}} --target benchmark_stack_counting -- -j 2 + - run: ${{github.workspace}}/build/bin/unit_test_queue_spsc + --gtest_shuffle + --gtest_color=yes +# - run: ${{github.workspace}}/build/bin/benchmark_sync From b06e3afaea005190e9a41798669f606eac68a82e Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Wed, 13 Sep 2023 23:41:16 +0200 Subject: [PATCH 06/10] add memory san --- .github/workflows/queue_spsc.yaml | 25 +++++++++++++++++++++++++ lockfree/queue/spsc/test/unit-tests.cpp | 6 +++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/queue_spsc.yaml b/.github/workflows/queue_spsc.yaml index 754186e..45b8431 100644 --- a/.github/workflows/queue_spsc.yaml +++ b/.github/workflows/queue_spsc.yaml @@ -35,6 +35,31 @@ jobs: --gtest_shuffle --gtest_color=yes + ubuntu-clang-15-debug-memorysanitize: + timeout-minutes: 15 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install Dependencies + uses: actions/cache@v2 + with: + path: ~/.conan/data + key: ${{ runner.os }}-conan-${{ hashFiles('conanfile.txt') }}-queue-spsc-address + - run: | + export BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} + ./tools/install_deps.sh + - run: | + mkdir -p ${{github.workspace}}/build + cmake -B ${{github.workspace}}/build -DCMAKE_CXX_COMPILER=/bin/${{env.CLANG_15}} -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE_DEBUG}} \ + -DCHECK_SANITIZE=ON -DENABLE_SANITIZER_MEMORY=True + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target queue_spsc -- -j 2 + cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE_DEBUG}} --target unit_test_queue_spsc -- -j 2 + - run: ${{github.workspace}}/build/bin/unit_test_queue_spsc + --gtest_shuffle + --gtest_color=yes + ubuntu-clang-15-debug-thread-sanitize: timeout-minutes: 15 runs-on: ubuntu-latest diff --git a/lockfree/queue/spsc/test/unit-tests.cpp b/lockfree/queue/spsc/test/unit-tests.cpp index 927e5d4..fc0d8a1 100644 --- a/lockfree/queue/spsc/test/unit-tests.cpp +++ b/lockfree/queue/spsc/test/unit-tests.cpp @@ -25,12 +25,12 @@ TEST_F(TestSPSCQueue, push_pop) { } TEST_F(TestSPSCQueue, only_pop) { - sync_cpp::SPSCQueue stack; + sync_cpp::SPSCQueue q; - auto empty = stack.pop(); + auto empty = q.pop(); ASSERT_FALSE(empty); - empty = stack.pop(); + empty = q.pop(); ASSERT_FALSE(empty); } From 3f45ecc45b6e10206e4d7d9a3d7ae051d6991b70 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Wed, 13 Sep 2023 23:50:27 +0200 Subject: [PATCH 07/10] up --- lockfree/queue/spsc/queue.h | 6 +++--- lockfree/queue/spsc/test/unit-tests.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lockfree/queue/spsc/queue.h b/lockfree/queue/spsc/queue.h index 55c40bf..02b4d6c 100644 --- a/lockfree/queue/spsc/queue.h +++ b/lockfree/queue/spsc/queue.h @@ -11,8 +11,8 @@ namespace sync_cpp { template class SPSCQueue final { struct Node final { - std::shared_ptr data; - Node* next; + std::shared_ptr data{}; + Node* next{nullptr}; }; std::atomic head_; @@ -39,7 +39,7 @@ class SPSCQueue final { void push(T new_value) { auto new_data = std::make_shared(std::move(new_value)); - Node* p = new Node(); + Node* p = new Node; Node* const old_tail = tail_.load(); old_tail->data.swap(new_data); old_tail->next = p; diff --git a/lockfree/queue/spsc/test/unit-tests.cpp b/lockfree/queue/spsc/test/unit-tests.cpp index fc0d8a1..fd9dd38 100644 --- a/lockfree/queue/spsc/test/unit-tests.cpp +++ b/lockfree/queue/spsc/test/unit-tests.cpp @@ -12,7 +12,7 @@ class TestSPSCQueue : public ::testing::Test { public: }; -TEST_F(TestSPSCQueue, push_pop) { +TEST_F(TestSPSCQueue, simple_push_pop) { sync_cpp::SPSCQueue q; q.push(117); From da032d4fd2685460a12d5e6805d9f312390793ea Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Wed, 13 Sep 2023 23:55:24 +0200 Subject: [PATCH 08/10] up --- lockfree/queue/spsc/queue.h | 1 + lockfree/queue/spsc/test/unit-tests.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lockfree/queue/spsc/queue.h b/lockfree/queue/spsc/queue.h index 02b4d6c..7cad758 100644 --- a/lockfree/queue/spsc/queue.h +++ b/lockfree/queue/spsc/queue.h @@ -35,6 +35,7 @@ class SPSCQueue final { SPSCQueue(SPSCQueue&&) noexcept = delete; ~SPSCQueue() { while (pop() != nullptr); + delete head_; } void push(T new_value) { diff --git a/lockfree/queue/spsc/test/unit-tests.cpp b/lockfree/queue/spsc/test/unit-tests.cpp index fd9dd38..7b833b1 100644 --- a/lockfree/queue/spsc/test/unit-tests.cpp +++ b/lockfree/queue/spsc/test/unit-tests.cpp @@ -25,7 +25,7 @@ TEST_F(TestSPSCQueue, simple_push_pop) { } TEST_F(TestSPSCQueue, only_pop) { - sync_cpp::SPSCQueue q; + sync_cpp::SPSCQueue q; auto empty = q.pop(); ASSERT_FALSE(empty); From 7fe755999207d7492c28cd891a4b41e386513042 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Thu, 14 Sep 2023 00:09:29 +0200 Subject: [PATCH 09/10] up another CI --- .github/workflows/cmake.yaml | 16 ++++++++-------- .github/workflows/mutex.yaml | 4 +++- .github/workflows/queue_spsc.yaml | 3 +-- .github/workflows/spinlock.yaml | 4 +++- .github/workflows/stack_counting.yaml | 4 +++- .github/workflows/stack_hazard_ptr.yaml | 4 +++- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cmake.yaml b/.github/workflows/cmake.yaml index 41dafee..e9c0d41 100644 --- a/.github/workflows/cmake.yaml +++ b/.github/workflows/cmake.yaml @@ -4,13 +4,13 @@ on: push: jobs: -# lockfree_stack_counting: -# uses: ./.github/workflows/stack_counting.yaml -# lockfree_stack_hazard: -# uses: ./.github/workflows/stack_hazard_ptr.yaml -# spinlock: -# uses: ./.github/workflows/spinlock.yaml -# mutex: -# uses: ./.github/workflows/mutex.yaml + lockfree_stack_counting: + uses: ./.github/workflows/stack_counting.yaml + lockfree_stack_hazard: + uses: ./.github/workflows/stack_hazard_ptr.yaml + spinlock: + uses: ./.github/workflows/spinlock.yaml + mutex: + uses: ./.github/workflows/mutex.yaml queue_spsc: uses: ./.github/workflows/queue_spsc.yaml \ No newline at end of file diff --git a/.github/workflows/mutex.yaml b/.github/workflows/mutex.yaml index 526b549..51822e9 100644 --- a/.github/workflows/mutex.yaml +++ b/.github/workflows/mutex.yaml @@ -1,7 +1,9 @@ name: Cmake on: - workflow_call: + push: + branches: + - master env: BUILD_TYPE_DEBUG: Debug diff --git a/.github/workflows/queue_spsc.yaml b/.github/workflows/queue_spsc.yaml index 45b8431..3cb07d9 100644 --- a/.github/workflows/queue_spsc.yaml +++ b/.github/workflows/queue_spsc.yaml @@ -1,7 +1,6 @@ name: Cmake -on: - workflow_call: +on: [push] env: BUILD_TYPE_DEBUG: Debug diff --git a/.github/workflows/spinlock.yaml b/.github/workflows/spinlock.yaml index c612b77..7d6793a 100644 --- a/.github/workflows/spinlock.yaml +++ b/.github/workflows/spinlock.yaml @@ -1,7 +1,9 @@ name: Cmake on: - workflow_call: + push: + branches: + - master env: BUILD_TYPE_DEBUG: Debug diff --git a/.github/workflows/stack_counting.yaml b/.github/workflows/stack_counting.yaml index ce95ad3..5d8e862 100644 --- a/.github/workflows/stack_counting.yaml +++ b/.github/workflows/stack_counting.yaml @@ -1,7 +1,9 @@ name: Cmake on: - workflow_call: + push: + branches: + - master env: BUILD_TYPE_DEBUG: Debug diff --git a/.github/workflows/stack_hazard_ptr.yaml b/.github/workflows/stack_hazard_ptr.yaml index 13f73e8..9237dd8 100644 --- a/.github/workflows/stack_hazard_ptr.yaml +++ b/.github/workflows/stack_hazard_ptr.yaml @@ -1,7 +1,9 @@ name: Cmake on: - workflow_call: + push: + branches: + - master env: BUILD_TYPE_DEBUG: Debug From e37228cc06a16bcfd3e96e116461f73b02983eb6 Mon Sep 17 00:00:00 2001 From: Konstantin Morozov Date: Thu, 14 Sep 2023 19:29:50 +0200 Subject: [PATCH 10/10] up dtor --- lockfree/queue/spsc/queue.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lockfree/queue/spsc/queue.h b/lockfree/queue/spsc/queue.h index 7cad758..a2a0d52 100644 --- a/lockfree/queue/spsc/queue.h +++ b/lockfree/queue/spsc/queue.h @@ -34,8 +34,10 @@ class SPSCQueue final { SPSCQueue(const SPSCQueue&) = delete; SPSCQueue(SPSCQueue&&) noexcept = delete; ~SPSCQueue() { - while (pop() != nullptr); - delete head_; + while (auto* const old_head = head_.load()) { + head_ = old_head->next; + delete old_head; + } } void push(T new_value) {