DEV: atomic strength for queues
This commit is contained in:
+24
-29
@@ -86,13 +86,18 @@ class deque {
|
||||
constexpr deque () noexcept :
|
||||
data_{},
|
||||
f{data_.data(), N},
|
||||
r{data_.data()} { }
|
||||
r{data_.data()} {
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
|
||||
//! fill contructor
|
||||
constexpr deque(const Data_t& value) noexcept {
|
||||
data_.fill(value);
|
||||
f = iterator(data_.data(), N);
|
||||
r = iterator(data_.data(), N);
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
|
||||
//! Initializer list contructor
|
||||
@@ -100,7 +105,10 @@ class deque {
|
||||
constexpr deque(It&& ...it) noexcept :
|
||||
data_{{std::forward<It>(it)...}},
|
||||
f(data_.data(), N),
|
||||
r(data_.data(), sizeof...(It)) { }
|
||||
r(data_.data(), sizeof...(It)) {
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
|
||||
deque(const deque&) = delete; //!< No copies
|
||||
deque& operator= (const deque&) = delete; //!< No copy assignments
|
||||
@@ -132,10 +140,10 @@ class deque {
|
||||
public:
|
||||
//! \return The size of the deque. The items currently in queue.
|
||||
constexpr size_t size() noexcept {
|
||||
return full() ? N: (r - f) -1;
|
||||
return r - (f +1);
|
||||
}
|
||||
constexpr size_t size() const noexcept {
|
||||
return full() ? N: (r - f) -1;
|
||||
return r - (f +1);
|
||||
}
|
||||
//! \return The maximum size of the deque. The items the queue can hold.
|
||||
constexpr size_t max_size() noexcept { return N; }
|
||||
@@ -144,11 +152,8 @@ class deque {
|
||||
//! \return True if the deque is empty
|
||||
constexpr bool empty() noexcept { return size() == 0 ? true : false; }
|
||||
//! \return True if the deque is full
|
||||
constexpr bool full() noexcept {
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
return (r == f) ? true : false;
|
||||
}
|
||||
constexpr bool full() noexcept { return size() == N ? true : false; }
|
||||
|
||||
//! @}
|
||||
|
||||
//! \name Member access
|
||||
@@ -166,36 +171,26 @@ class deque {
|
||||
//! \param it The item to push
|
||||
constexpr void push_front (const Data_t& it) noexcept {
|
||||
if (full()) return;
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
*f-- = it;
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
}
|
||||
//! \brief Extract an item from the front of the deque and remove it from the deque
|
||||
//! \param it The item to push
|
||||
constexpr Data_t pop_front () noexcept {
|
||||
if (empty()) return Data_t{};
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
return *++f;
|
||||
*f = it;
|
||||
--f; // keep this separate for thread safety
|
||||
}
|
||||
//! \brief Push an item in the back of the deque
|
||||
//! \param it The item to push
|
||||
constexpr void push_back (const Data_t& it) noexcept {
|
||||
if (full()) return;
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
*r++ = it;
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
*r = it;
|
||||
++r; // keep this separate for thread safety
|
||||
}
|
||||
//! \brief Extract an item from the front of the deque and remove it from the deque
|
||||
//! \param it The item to push
|
||||
constexpr Data_t pop_front () noexcept {
|
||||
if (empty()) return Data_t{};
|
||||
return *++f;
|
||||
}
|
||||
//! \brief Extract an item from the back of the deque and remove it from the deque
|
||||
//! \param it The item to push
|
||||
constexpr Data_t pop_back () noexcept {
|
||||
if (empty()) return Data_t{};
|
||||
if constexpr (SemiAtomic)
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
return *--r;
|
||||
}
|
||||
|
||||
|
||||
@@ -191,21 +191,21 @@ class edeque : public deque<Data_t, N, SemiAtomic> {
|
||||
}
|
||||
//! @}
|
||||
|
||||
//! \name Base class overwrites
|
||||
//! \name Base class uses and overwrites
|
||||
//! @{
|
||||
void push_front (const Data_t& it) noexcept {
|
||||
base_type::push_front(it);
|
||||
check_trigger_push_async_(it);
|
||||
}
|
||||
void push_back (const Data_t& it) noexcept {
|
||||
base_type::push_back(it);
|
||||
check_trigger_push_async_(it);
|
||||
}
|
||||
Data_t pop_front () noexcept {
|
||||
Data_t t = base_type::pop_front();
|
||||
check_trigger_pop_async_(t);
|
||||
return t;
|
||||
}
|
||||
void push_back (const Data_t& it) noexcept {
|
||||
base_type::push_back(it);
|
||||
check_trigger_push_async_(it);
|
||||
}
|
||||
Data_t pop_back () noexcept {
|
||||
Data_t t = base_type::pop_back();
|
||||
check_trigger_pop_async_(t);
|
||||
|
||||
Reference in New Issue
Block a user