From beb4da220014b5c23afd50fce028809c57d519f8 Mon Sep 17 00:00:00 2001 From: Max Kanushin Date: Sun, 28 Jan 2018 20:56:20 +0300 Subject: [PATCH 1/3] added dummy unit tests --- test/unit/set/CMakeLists.txt | 10 +++++ test/unit/set/lazy_skiplist.cpp | 66 +++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 test/unit/set/lazy_skiplist.cpp diff --git a/test/unit/set/CMakeLists.txt b/test/unit/set/CMakeLists.txt index 0487d6617..dafc97b30 100644 --- a/test/unit/set/CMakeLists.txt +++ b/test/unit/set/CMakeLists.txt @@ -77,6 +77,16 @@ add_executable(${UNIT_SET_SKIP} ${UNIT_SET_SKIP_SOURCES}) target_link_libraries(${UNIT_SET_SKIP} ${CDS_TEST_LIBRARIES}) add_test(NAME ${UNIT_SET_SKIP} COMMAND ${UNIT_SET_SKIP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) +# LazySkipListSet +set(UNIT_SET_LAZY_SKIP unit-set-lazy-skip) +set(UNIT_SET_LAZY_SKIP_SOURCES + ../main.cpp + lazy_skiplist.cpp + ) +add_executable(${UNIT_SET_LAZY_SKIP} ${UNIT_SET_LAZY_SKIP_SOURCES}) +target_link_libraries(${UNIT_SET_LAZY_SKIP} ${CDS_TEST_LIBRARIES}) +add_test(NAME ${UNIT_SET_LAZY_SKIP} COMMAND ${UNIT_SET_SKIP} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) + # SplitListSet set(UNIT_SET_SPLIT_MICHAEL unit-set-split-michael) set(UNIT_SET_SPLIT_MICHAEL_SOURCES diff --git a/test/unit/set/lazy_skiplist.cpp b/test/unit/set/lazy_skiplist.cpp new file mode 100644 index 000000000..50d9c988d --- /dev/null +++ b/test/unit/set/lazy_skiplist.cpp @@ -0,0 +1,66 @@ +#include + +#include +#include + +template +using Set = cds::container::LazySkipListSet; + +typedef int value_type; + +TEST(LazyTest, test_insert) { + Set set; + + ASSERT_TRUE(set.insert(42)); + ASSERT_TRUE(set.insert(41)); + ASSERT_TRUE(set.insert(43)); + + ASSERT_FALSE(set.insert(42)); + ASSERT_FALSE(set.insert(43.0f)); + ASSERT_FALSE(set.insert(41)); + + ASSERT_TRUE(set.insert(-41)); +} + +TEST(LazyTest, test_contains) { + Set set; + + ASSERT_FALSE(set.contains(42)); + ASSERT_FALSE(set.contains(43)); + + set.insert(42); + ASSERT_TRUE(set.contains(42)); + ASSERT_FALSE(set.contains(43)); + + set.insert(43); + ASSERT_TRUE(set.contains(42)); + ASSERT_TRUE(set.contains(43)); +} + +TEST(LazyTest, test_remove) { + Set set; + + ASSERT_FALSE(set.remove(42)); + + set.insert(42); + ASSERT_TRUE(set.remove(42)); + ASSERT_FALSE(set.remove(42)); +} + +TEST(LazyTest, test_empty) { + Set set; + + ASSERT_TRUE(set.empty()); + + set.insert(42); + ASSERT_FALSE(set.empty()); + + set.insert(43); + ASSERT_FALSE(set.empty()); + + set.remove(42); + ASSERT_FALSE(set.empty()); + + set.remove(43); + ASSERT_TRUE(set.empty()); +} From 3eccd585695081bb974add33264bf96fb6c88431 Mon Sep 17 00:00:00 2001 From: Max Kanushin Date: Sun, 28 Jan 2018 22:52:22 +0300 Subject: [PATCH 2/3] removed gc::atomic_marked_pointer --- .../details/lazy_skip_list_set_base.h | 45 ++++++++----------- cds/container/lazy_skip_list_set_dhp.h | 32 ++++++------- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/cds/container/details/lazy_skip_list_set_base.h b/cds/container/details/lazy_skip_list_set_base.h index bcb0be225..c5a42d68e 100644 --- a/cds/container/details/lazy_skip_list_set_base.h +++ b/cds/container/details/lazy_skip_list_set_base.h @@ -2,6 +2,7 @@ #define CDSLIB_LAZY_SKIP_LIST_BASE_H #include +#include namespace cds { namespace container { @@ -19,28 +20,25 @@ namespace cds { namespace container { class node { public: - typedef GC gc; - typedef T value_type; - typedef Lock lock_type; + typedef cds::gc::nogc gc; + typedef T value_type; + typedef Lock lock_type; typedef std::size_t key_type; typedef node* node_ptr; typedef std::numeric_limits limits; - typedef cds::details::Allocator node_allocator; - typedef cds::details::marked_ptr marked_ptr; - typedef typename gc::template atomic_marked_ptr atomic_marked_ptr; - - typedef cds::details::Allocator tower_allocator; + typedef cds::details::Allocator node_allocator; + typedef cds::details::Allocator tower_allocator; protected: value_type value; key_type key; unsigned int m_nHeight; - atomic_marked_ptr * m_arrNext; + node_ptr * m_arrNext; atomics::atomic _marked; - atomics::atomic fullyLinked; + atomics::atomic _fully_linked; key_type hash() { return std::hash{}(value); @@ -49,7 +47,7 @@ namespace cds { namespace container { public: lock_type lock; - node() : _marked(false), fullyLinked(false) { + node() : _marked(false), _fully_linked(false) { } @@ -58,31 +56,26 @@ namespace cds { namespace container { } bool marked() { - return _marked; + return _marked.load(); } bool mark() { - _marked = true; - } - - bool mark_hard() { - marked_ptr next_marked(next(0).load(atomics::memory_order_relaxed).ptr()); - next(0).compare_exchange_strong(next_marked, next_marked | 1, atomics::memory_order_release, atomics::memory_order_acquire); + _marked.store(true); } bool fully_linked() { - return fullyLinked.load(atomics::memory_order_relaxed); + return _fully_linked.load(); } void set_fully_linked(bool value) { - fullyLinked.store(value, atomics::memory_order_relaxed); + _fully_linked.store(value); } key_type node_key() { return key; } - atomic_marked_ptr& next(unsigned int nLevel) { + node_ptr& next(unsigned int nLevel) { return m_arrNext[nLevel]; } @@ -107,8 +100,8 @@ namespace cds { namespace container { ta.Delete(pNode->release_tower(), topLayer + 1); } - atomic_marked_ptr * release_tower() { - atomic_marked_ptr * pTower = m_arrNext; + node_ptr * release_tower() { + node_ptr * pTower = m_arrNext; m_arrNext = nullptr; m_nHeight = 0; @@ -121,7 +114,7 @@ namespace cds { namespace container { new_node->key = key; new_node->m_nHeight = cds::container::lazy_skip_list_set::c_nMaxHeight; new_node->allocate_tower(new_node->m_nHeight); - new_node->fullyLinked = false; + new_node->_fully_linked = false; return new_node; } @@ -133,7 +126,7 @@ namespace cds { namespace container { new_node->value = v; new_node->key = new_node->hash(); new_node->m_nHeight = topLayer; - new_node->fullyLinked = false; + new_node->_fully_linked = false; new_node->allocate_tower(topLayer + 1); @@ -147,7 +140,7 @@ namespace cds { namespace container { } static node * max_key() { - node_ptr new_node = allocate_node(limits::max() / 1000); + node_ptr new_node = allocate_node(limits::max()); return new_node; } diff --git a/cds/container/lazy_skip_list_set_dhp.h b/cds/container/lazy_skip_list_set_dhp.h index 27ebdb67f..247173c78 100644 --- a/cds/container/lazy_skip_list_set_dhp.h +++ b/cds/container/lazy_skip_list_set_dhp.h @@ -4,6 +4,7 @@ #include #include +#include namespace cds { namespace container { @@ -15,12 +16,12 @@ namespace cds { namespace container { class LazySkipListSet { public: - typedef GC gc; - typedef T value_type; - typedef Traits traits; + typedef cds::gc::nogc gc; + typedef T value_type; + typedef Traits traits; static size_t const c_nMaxHeight = cds::container::lazy_skip_list_set::c_nMaxHeight; - // static size_t const c_nHazardPtrCount = c_nMaxHeight * 2 + 3; + static size_t const c_nHazardPtrCount = 0; typedef typename traits::random_level_generator rand_height; @@ -39,7 +40,7 @@ namespace cds { namespace container { m_Tail = node_type::max_key(); for (unsigned int layer = 0; layer < c_nMaxHeight; layer++) - m_Head->next(layer).store(marked_ptr(m_Tail), traits::memory_model::memory_order_relaxed); + m_Head->next(layer) = m_Tail; } ~LazySkipListSet() { @@ -90,8 +91,8 @@ namespace cds { namespace container { node_type *new_node = node_type::allocate_node(v, topLayer); for (unsigned int layer = 0; layer <= topLayer; layer++) { - new_node->next(layer).store(marked_ptr(succs[layer])); - preds[layer]->next(layer).store(marked_ptr(new_node)); + new_node->next(layer) = succs[layer]; + preds[layer]->next(layer) = new_node; } new_node->set_fully_linked(true); @@ -154,10 +155,10 @@ namespace cds { namespace container { continue; for (unsigned int layer = topLayer; layer >= 0 && layer < c_nMaxHeight; layer--) - preds[layer]->next(layer).store(nodeToDelete->next(layer), atomics::memory_order_relaxed); + preds[layer]->next(layer) = nodeToDelete->next(layer); nodeToDelete->lock.unlock(); - nodeToDelete->mark_hard(); + node_type::dispose_node(nodeToDelete); unlock(preds, highestLocked); return true; } catch (int e) { @@ -184,15 +185,14 @@ namespace cds { namespace container { } bool empty() { - // FIXME - node_type *succ = m_Head->next(0).load(traits::memory_model::memory_order_relaxed).ptr(); + node_type *succ = m_Head->next(0); while (true) { if (m_Head->next(0) == m_Tail) return true; if (succ->marked()) - succ = m_Head->next(0).load(traits::memory_model::memory_order_relaxed).ptr(); + succ = m_Head->next(0); else return false; } @@ -200,9 +200,9 @@ namespace cds { namespace container { protected: void destroy() { - node_type *p = m_Head; //->next(0).load(atomics::memory_order_relaxed).ptr(); + node_type *p = m_Head; while (p) { - node_type *pNext = p->next(0).load(atomics::memory_order_relaxed).ptr(); + node_type *pNext = p->next(0); node_type::dispose_node(p); p = pNext; } @@ -223,11 +223,11 @@ namespace cds { namespace container { node_type *pred = m_Head; for (unsigned int layer = c_nMaxHeight - 1; layer >= 0 && layer < c_nMaxHeight; layer--) { - node_type *curr = pred->next(layer).load(traits::memory_model::memory_order_relaxed).ptr(); + node_type *curr = pred->next(layer); while (key > curr->node_key()) { pred = curr; - curr = pred->next(layer).load(traits::memory_model::memory_order_relaxed).ptr(); + curr = pred->next(layer); } if (lFound == -1 && key == curr->node_key()) From 1552f378c2bf0cb89be4fa8ae11a45f41adf6a6b Mon Sep 17 00:00:00 2001 From: Max Kanushin Date: Sun, 28 Jan 2018 22:57:41 +0300 Subject: [PATCH 3/3] renamed files --- .../{lazy_skip_list_set_dhp.h => lazy_skip_list_set.h} | 0 test/unit/set/lazy_skiplist.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename cds/container/{lazy_skip_list_set_dhp.h => lazy_skip_list_set.h} (100%) diff --git a/cds/container/lazy_skip_list_set_dhp.h b/cds/container/lazy_skip_list_set.h similarity index 100% rename from cds/container/lazy_skip_list_set_dhp.h rename to cds/container/lazy_skip_list_set.h diff --git a/test/unit/set/lazy_skiplist.cpp b/test/unit/set/lazy_skiplist.cpp index 50d9c988d..502baaf41 100644 --- a/test/unit/set/lazy_skiplist.cpp +++ b/test/unit/set/lazy_skiplist.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include template using Set = cds::container::LazySkipListSet;