From 98ae70bb4b0d504f466becea40ad0b49882cbec2 Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Mon, 13 May 2019 16:29:43 +0200 Subject: [PATCH] Refactor: Pull stamped integer into own file. --- lib/pls/CMakeLists.txt | 1 + lib/pls/include/pls/internal/data_structures/stamped_integer.h | 27 +++++++++++++++++++++++++++ lib/pls/include/pls/internal/data_structures/work_stealing_deque.h | 16 ++++------------ lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h | 14 +++++++------- 4 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 lib/pls/include/pls/internal/data_structures/stamped_integer.h diff --git a/lib/pls/CMakeLists.txt b/lib/pls/CMakeLists.txt index 7ad7187..d834402 100644 --- a/lib/pls/CMakeLists.txt +++ b/lib/pls/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(pls STATIC include/pls/internal/data_structures/aligned_stack_impl.h include/pls/internal/data_structures/deque.h src/internal/data_structures/deque.cpp include/pls/internal/data_structures/work_stealing_deque.h include/pls/internal/data_structures/work_stealing_deque_impl.h + include/pls/internal/data_structures/stamped_integer.h include/pls/internal/helpers/prohibit_new.h include/pls/internal/helpers/profiler.h diff --git a/lib/pls/include/pls/internal/data_structures/stamped_integer.h b/lib/pls/include/pls/internal/data_structures/stamped_integer.h new file mode 100644 index 0000000..a24bcfa --- /dev/null +++ b/lib/pls/include/pls/internal/data_structures/stamped_integer.h @@ -0,0 +1,27 @@ + +#ifndef PREDICTABLE_PARALLEL_PATTERNS_LIB_PLS_INCLUDE_PLS_INTERNAL_DATA_STRUCTURES_STAMPED_INTEGER_H_ +#define PREDICTABLE_PARALLEL_PATTERNS_LIB_PLS_INCLUDE_PLS_INTERNAL_DATA_STRUCTURES_STAMPED_INTEGER_H_ + +#include "pls/internal/base/system_details.h" + +namespace pls { +namespace internal { +namespace data_structures { + +constexpr unsigned long HALF_CACHE_LINE = base::system_details::CACHE_LINE_SIZE / 2; +struct stamped_integer { + using member_t = base::system_details::cas_integer; + + member_t stamp:HALF_CACHE_LINE; + member_t value:HALF_CACHE_LINE; + + stamped_integer() : stamp{0}, value{0} {}; + stamped_integer(member_t new_value) : stamp{0}, value{new_value} {}; + stamped_integer(member_t new_stamp, member_t new_value) : stamp{new_stamp}, value{new_value} {}; +}; + +} +} +} + +#endif //PREDICTABLE_PARALLEL_PATTERNS_LIB_PLS_INCLUDE_PLS_INTERNAL_DATA_STRUCTURES_STAMPED_INTEGER_H_ diff --git a/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h b/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h index 633e203..3bddd82 100644 --- a/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h +++ b/lib/pls/include/pls/internal/data_structures/work_stealing_deque.h @@ -4,9 +4,9 @@ #include -#include "pls/internal/scheduling/thread_state.h" -#include "pls/internal/base/system_details.h" #include "pls/internal/base/error_handling.h" +#include "pls/internal/data_structures/stamped_integer.h" +#include "pls/internal/scheduling/thread_state.h" #include "aligned_stack.h" @@ -17,16 +17,8 @@ namespace data_structures { using base::system_details::pointer_t; // Integer split into two halfs, can be used in CAS operations -constexpr unsigned long HALF_CACHE_LINE = base::system_details::CACHE_LINE_SIZE / 2; -using offset_t = base::system_details::cas_integer; -struct stamped_integer { - offset_t stamp:HALF_CACHE_LINE; - offset_t offset:HALF_CACHE_LINE; - - stamped_integer() : stamp{0}, offset{0} {}; - stamped_integer(offset_t new_offset) : stamp{0}, offset{new_offset} {}; - stamped_integer(offset_t new_stamp, offset_t new_offset) : stamp{new_stamp}, offset{new_offset} {}; -}; +using data_structures::stamped_integer; +using offset_t = stamped_integer::member_t; // Single Item in the deque class work_stealing_deque_item { diff --git a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h index 990e9e8..ea860a2 100644 --- a/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h +++ b/lib/pls/include/pls/internal/data_structures/work_stealing_deque_impl.h @@ -61,7 +61,7 @@ Item *work_stealing_deque::pop_tail() { offset_t local_tail = tail_; stamped_integer local_head = head_; - if (local_tail <= local_head.offset) { + if (local_tail <= local_head.value) { return nullptr; // EMPTY } @@ -74,11 +74,11 @@ Item *work_stealing_deque::pop_tail() { // Get the state of local head AFTER we published our wish local_head = head_; // Linearization point, outside knows list is empty - if (local_head.offset < new_tail) { + if (local_head.value < new_tail) { return previous_tail_item->data(); // Success, enough distance to other threads } - if (local_head.offset == new_tail) { + if (local_head.value == new_tail) { stamped_integer new_head = stamped_integer{local_head.stamp + 1, new_tail}; // Try competing with consumers by updating the head's stamp value if (head_.compare_exchange_strong(local_head, new_head)) { @@ -89,7 +89,7 @@ Item *work_stealing_deque::pop_tail() { // Some other thread either won the competition or it already set the head further than we are // before we even tried to compete with it. // Reset the queue into an empty state => head_ = tail_ - tail_ = local_head.offset; // ...we give up to the other winning thread + tail_ = local_head.value; // ...we give up to the other winning thread return nullptr; // EMPTY, we lost the competition with other threads } @@ -99,14 +99,14 @@ Item *work_stealing_deque::pop_head() { stamped_integer local_head = head_; offset_t local_tail = tail_; - if (local_tail <= local_head.offset) { + if (local_tail <= local_head.value) { return nullptr; // EMPTY } // Load info on current deque item. // In case we have a race with a new (aba) overwritten item at this position, // there has to be a competition over the tail -> the stamp increased and our next // operation will fail anyways! - work_stealing_deque_item *head_deque_item = item_at(local_head.offset); + work_stealing_deque_item *head_deque_item = item_at(local_head.value); offset_t next_item_offset = head_deque_item->next_item(); Item *head_data_item = head_deque_item->data(); @@ -134,7 +134,7 @@ void work_stealing_deque::release_memory_until(state state) { if (item_offset < local_tail) { tail_ = item_offset; - if (local_head.offset >= local_tail) { + if (local_head.value >= local_tail) { head_ = stamped_integer{local_head.stamp + 1, item_offset}; } } -- libgit2 0.26.0