From 5c336403ecf4381ea8548eb7d358c714662d1588 Mon Sep 17 00:00:00 2001 From: Martin Wudenka Date: Mon, 11 Sep 2023 07:42:26 +0200 Subject: [PATCH 1/3] fix: Add missing includes --- include/crill/reclaim_object.h | 2 ++ include/crill/reclaim_on_write_object.h | 2 ++ tests/utility_test.cpp | 1 + 3 files changed, 5 insertions(+) diff --git a/include/crill/reclaim_object.h b/include/crill/reclaim_object.h index 401af4d..3d2b53c 100644 --- a/include/crill/reclaim_object.h +++ b/include/crill/reclaim_object.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include diff --git a/include/crill/reclaim_on_write_object.h b/include/crill/reclaim_on_write_object.h index 115cc33..6fe5757 100644 --- a/include/crill/reclaim_on_write_object.h +++ b/include/crill/reclaim_on_write_object.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include namespace crill { diff --git a/tests/utility_test.cpp b/tests/utility_test.cpp index 0b1d399..2fd6291 100644 --- a/tests/utility_test.cpp +++ b/tests/utility_test.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include "tests.h" From e1eee8ae2fbbe90757d07710dbaf7e3afbd0b38e Mon Sep 17 00:00:00 2001 From: Martin Wudenka Date: Mon, 11 Sep 2023 10:02:19 +0200 Subject: [PATCH 2/3] [rcu] use unique_ptr with custom deleter as read_ptr --- include/crill/reclaim_object.h | 54 +++++++++++++--------------------- tests/reclaim_object_test.cpp | 11 +++++-- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/include/crill/reclaim_object.h b/include/crill/reclaim_object.h index 3d2b53c..4797503 100644 --- a/include/crill/reclaim_object.h +++ b/include/crill/reclaim_object.h @@ -63,50 +63,37 @@ class reclaim_object // Reading the value must happen through a reader class. class reader; - // read_ptr provides scoped read access to the value. - class read_ptr + // custom deleter for read-only unique_ptr + struct read_ptr_deleter { - public: - read_ptr(reader& rdr) noexcept - : rdr(rdr) + // constexpr read_ptr_deleter() noexcept = default; + explicit constexpr read_ptr_deleter(reader& rdr) noexcept : rdr(&rdr) { assert(rdr.min_epoch == 0); - rdr.min_epoch.store(rdr.obj.current_epoch.load()); assert(rdr.min_epoch =! 0); + }; - value_read = rdr.obj.value.load(); - assert(value_read); - } - - ~read_ptr() - { - assert(rdr.min_epoch != 0); - rdr.min_epoch.store(0); - } + read_ptr_deleter(const read_ptr_deleter &) noexcept = default; + read_ptr_deleter(read_ptr_deleter &&) noexcept = default; + read_ptr_deleter &operator=(read_ptr_deleter const &) noexcept = default; + read_ptr_deleter &operator=(read_ptr_deleter &&) noexcept = default; - const T& operator*() const + void operator()(const T*) const { - assert(value_read); - return *value_read; + if (rdr) + { + assert(rdr->min_epoch != 0); + rdr->min_epoch.store(0); + } } - const T* operator->() const - { - assert(value_read); - return value_read; - } - - read_ptr(read_ptr&&) = delete; - read_ptr& operator=(read_ptr&&) = delete; - read_ptr(const read_ptr&) = delete; - read_ptr& operator=(const read_ptr&) = delete; - private: - reader& rdr; - T* value_read = nullptr; + reader* rdr; }; + using read_ptr = std::unique_ptr; + class reader { public: @@ -132,12 +119,13 @@ class reclaim_object // Non-blocking guarantees: wait-free. read_ptr read_lock() noexcept { - return read_ptr(*this); + auto deleter = read_ptr_deleter(*this); + return read_ptr(obj.value.load(), std::move(deleter)); } private: friend class reclaim_object; - friend class read_ptr; + friend class read_ptr_deleter; reclaim_object& obj; std::atomic min_epoch = 0; }; diff --git a/tests/reclaim_object_test.cpp b/tests/reclaim_object_test.cpp index c45ce81..753e93d 100644 --- a/tests/reclaim_object_test.cpp +++ b/tests/reclaim_object_test.cpp @@ -42,13 +42,18 @@ TEST_CASE("reclaim_object::read_ptr") crill::reclaim_object obj(3, 'x'); auto reader = obj.get_reader(); - SUBCASE("read_ptr is not copyable or movable") + SUBCASE("read_ptr is not copyable") { auto read_ptr = reader.read_lock(); static_assert(!std::is_copy_constructible_v); static_assert(!std::is_copy_assignable_v); - static_assert(!std::is_move_constructible_v); - static_assert(!std::is_move_assignable_v); + } + + SUBCASE("read_ptr is movable movable") + { + auto read_ptr = reader.read_lock(); + static_assert(std::is_move_constructible_v); + static_assert(std::is_move_assignable_v); } SUBCASE("Dereference") From 4b5f65be96489ecf6e3516955943bddfba4fd219 Mon Sep 17 00:00:00 2001 From: Martin Wudenka Date: Mon, 11 Sep 2023 10:34:14 +0200 Subject: [PATCH 3/3] [rcu] allow creation of null read_ptr --- include/crill/reclaim_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/crill/reclaim_object.h b/include/crill/reclaim_object.h index 4797503..010f6e9 100644 --- a/include/crill/reclaim_object.h +++ b/include/crill/reclaim_object.h @@ -66,7 +66,7 @@ class reclaim_object // custom deleter for read-only unique_ptr struct read_ptr_deleter { - // constexpr read_ptr_deleter() noexcept = default; + constexpr read_ptr_deleter() noexcept = default; explicit constexpr read_ptr_deleter(reader& rdr) noexcept : rdr(&rdr) { assert(rdr.min_epoch == 0);