diff --git a/lib/pls/CMakeLists.txt b/lib/pls/CMakeLists.txt index bba3227..bad2b80 100644 --- a/lib/pls/CMakeLists.txt +++ b/lib/pls/CMakeLists.txt @@ -1,6 +1,6 @@ # List all required files here (cmake best practice to NOT automate this step!) add_library(pls STATIC - src/library.cpp include/pls/library.h + src/pls.cpp include/pls/pls.h src/internal/base/spin_lock.cpp include/pls/internal/base/spin_lock.h src/internal/base/thread.cpp include/pls/internal/base/thread.h include/pls/internal/base/prohibit_new.h @@ -13,7 +13,7 @@ add_library(pls STATIC include/pls/internal/base/system_details.h src/internal/scheduling/run_on_n_threads_task.cpp include/pls/internal/scheduling/run_on_n_threads_task.h src/internal/scheduling/tbb_task.cpp include/pls/internal/scheduling/tbb_task.h - ) + src/internal/base/deque.cpp include/pls/internal/base/deque.h) # Add everything in `./include` to be in the include path of this project target_include_directories(pls diff --git a/lib/pls/include/pls/internal/base/deque.h b/lib/pls/include/pls/internal/base/deque.h new file mode 100644 index 0000000..5fbe0bb --- /dev/null +++ b/lib/pls/include/pls/internal/base/deque.h @@ -0,0 +1,51 @@ + +#ifndef PLS_DEQUE_H +#define PLS_DEQUE_H + +#include "spin_lock.h" + +namespace pls { + namespace internal { + namespace base { + class deque_item { + friend class deque_internal; + + deque_item* prev_; + deque_item* next_; + + }; + + class deque_internal { + protected: + deque_item* head_; + deque_item* tail_; + + spin_lock lock_; + + deque_item* pop_head_internal(); + deque_item* pop_tail_internal(); + void push_tail_internal(deque_item *new_item); + }; + + template + class deque: deque_internal { + public: + explicit deque(): deque_internal{} {} + + inline Item* pop_head() { + return static_cast(pop_head_internal()); + } + + inline Item* pop_tail() { + return static_cast(pop_tail_internal()); + } + + inline void push_tail(Item* new_item) { + push_tail_internal(new_item); + } + }; + } + } +} + +#endif //PLS_DEQUE_H diff --git a/lib/pls/src/internal/base/deque.cpp b/lib/pls/src/internal/base/deque.cpp new file mode 100644 index 0000000..5370a91 --- /dev/null +++ b/lib/pls/src/internal/base/deque.cpp @@ -0,0 +1,58 @@ +#include + +#include "pls/internal/base/deque.h" + +namespace pls { + namespace internal { + namespace base { + deque_item* deque_internal::pop_head_internal() { + std::lock_guard lock{lock_}; + + if (head_ == nullptr) { + return nullptr; + } + + deque_item* result = head_; + head_ = head_->prev_; + if (head_ == nullptr) { + tail_ = nullptr; + } else { + head_->next_ = nullptr; + } + + return result; + } + + deque_item* deque_internal::pop_tail_internal() { + std::lock_guard lock{lock_}; + + if (tail_ == nullptr) { + return nullptr; + } + + deque_item* result = tail_; + tail_ = tail_->next_; + if (tail_ == nullptr) { + head_ = nullptr; + } else { + tail_->prev_ = nullptr; + } + + return result; + } + + void deque_internal::push_tail_internal(deque_item *new_item) { + std::lock_guard lock{lock_}; + + if (tail_ != nullptr) { + tail_->prev_ = new_item; + } else { + head_ = new_item; + } + new_item->next_ = tail_; + new_item->prev_ = nullptr; + tail_ = new_item; + } + } + } +}