diff --git a/lib/pls/include/pls/internal/scheduling/tbb_task.h b/lib/pls/include/pls/internal/scheduling/tbb_task.h index c393808..70d34da 100644 --- a/lib/pls/include/pls/internal/scheduling/tbb_task.h +++ b/lib/pls/include/pls/internal/scheduling/tbb_task.h @@ -2,7 +2,9 @@ #ifndef PLS_TBB_LIKE_TASK_H #define PLS_TBB_LIKE_TASK_H -#include +#include "pls/internal/base/aligned_stack.h" +#include "pls/internal/base/deque.h" + #include "abstract_task.h" #include "thread_state.h" @@ -10,7 +12,7 @@ namespace pls { namespace internal { namespace scheduling { class tbb_task; - class tbb_sub_task { + class tbb_sub_task: public base::deque_item { friend class tbb_task; // Coordinate finishing of sub_tasks @@ -20,10 +22,6 @@ namespace pls { // Access to TBB scheduling environment tbb_task* tbb_task_; - // Double-Ended Queue management - tbb_sub_task* below_; - tbb_sub_task* above_; - // Stack Management (reset stack pointer after wait_for_all() calls) base::aligned_stack::state stack_state_; protected: @@ -60,9 +58,7 @@ namespace pls { base::aligned_stack* my_stack_; // Double-Ended Queue management - base::spin_lock lock_; - tbb_sub_task* top_; - tbb_sub_task* bottom_; + base::deque deque_; // Steal Management tbb_sub_task* last_stolen_; @@ -77,8 +73,7 @@ namespace pls { explicit tbb_task(tbb_sub_task* root_task): abstract_task{0, 0}, root_task_{root_task}, - top_{nullptr}, - bottom_{nullptr}, + deque_{}, last_stolen_{nullptr} { my_stack_ = base::this_thread::state()->task_stack_; root_task_->tbb_task_ = this; diff --git a/lib/pls/src/internal/scheduling/tbb_task.cpp b/lib/pls/src/internal/scheduling/tbb_task.cpp index c2e825d..87c3cab 100644 --- a/lib/pls/src/internal/scheduling/tbb_task.cpp +++ b/lib/pls/src/internal/scheduling/tbb_task.cpp @@ -5,13 +5,13 @@ namespace pls { namespace internal { namespace scheduling { tbb_sub_task::tbb_sub_task(): + base::deque_item{}, ref_count_{0}, parent_{nullptr}, tbb_task_{nullptr}, - below_{nullptr}, - above_{nullptr} {} + stack_state_{nullptr} {} - tbb_sub_task::tbb_sub_task(const tbb_sub_task& /*other*/) { + tbb_sub_task::tbb_sub_task(const tbb_sub_task& other): base::deque_item(other) { // Do Nothing, will be inited after this anyways } @@ -33,18 +33,7 @@ namespace pls { sub_task->tbb_task_ = tbb_task_; sub_task->stack_state_ = tbb_task_->my_stack_->save_state(); - // Put sub_task into stealing queue - { - std::lock_guard lock{tbb_task_->lock_}; - if (tbb_task_->bottom_ != nullptr) { - tbb_task_->bottom_->below_ = sub_task; - } else { - tbb_task_->top_ = sub_task; - } - sub_task->above_ = tbb_task_->bottom_; - sub_task->below_ = nullptr; - tbb_task_->bottom_ = sub_task; - } + tbb_task_->deque_.push_tail(sub_task); } void tbb_sub_task::wait_for_all() { @@ -64,41 +53,11 @@ namespace pls { } tbb_sub_task* tbb_task::get_local_sub_task() { - // Remove from bottom of queue - std::lock_guard lock{lock_}; - - if (bottom_ == nullptr) { - return nullptr; - } - - tbb_sub_task *result = bottom_; - bottom_ = bottom_->above_; - if (bottom_ == nullptr) { - top_ = nullptr; - } else { - bottom_->below_ = nullptr; - } - - return result; + return deque_.pop_tail(); } tbb_sub_task* tbb_task::get_stolen_sub_task() { - // Remove from top of queue - std::lock_guard lock{lock_}; - - if (top_ == nullptr) { - return nullptr; - } - - tbb_sub_task *result = top_; - top_ = top_->below_; - if (top_ == nullptr) { - bottom_ = nullptr; - } else { - top_->above_ = nullptr; - } - - return result; + return deque_.pop_head(); } bool tbb_task::internal_stealing(abstract_task* other_task) {