task.cpp 1.04 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include "pls/internal/helpers/profiler.h"

#include "pls/internal/scheduling/scheduler.h"
#include "pls/internal/scheduling/task.h"
#include "pls/internal/scheduling/thread_state.h"

namespace pls {
namespace internal {
namespace scheduling {

task::task() :
    ref_count_{0},
    parent_{nullptr},
    deque_state_{0} {}

task::task(const task &other) :
    ref_count_{0},
    parent_{other.parent_},
    deque_state_{other.deque_state_} {}

void task::execute() {
22 23 24
  PROFILE_WORK_BLOCK("execute task")
  auto last_executing = thread_state::get()->current_task_;
  thread_state::get()->current_task_ = this;
25

26 27
  execute_internal();
  PROFILE_END_BLOCK
28 29

  wait_for_all();
30
  thread_state::get()->current_task_ = last_executing;
31 32 33 34 35 36

  if (parent_ != nullptr) {
    parent_->ref_count_--;
  }
}

37
void task::wait_for_all() {
38 39
  auto scheduler = thread_state::get()->scheduler_;

40
  while (ref_count_ > 0) {
41 42
    if (!scheduler->try_execute_local()) {
      scheduler->try_execute_stolen();
43 44 45
    }
  }
  thread_state::get()->deque_.release_memory_until(deque_state_);
46 47 48 49 50
}

}
}
}