task.cpp 1.16 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#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() :
12
    finished_construction_{false},
13 14
    ref_count_{0},
    parent_{nullptr},
15
    deque_offset_{0} {}
16

17 18 19 20
void *task::allocate_memory(long size) {
  if (finished_construction_) {
    PLS_ERROR("Must not allocate dynamic task memory after it's construction.")
  }
21
  return thread_state::get()->deque_.push_bytes(size);
22 23
}

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

29 30
  execute_internal();
  PROFILE_END_BLOCK
31 32

  wait_for_all();
33
  thread_state::get()->current_task_ = last_executing;
34 35 36 37 38 39

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

40
void task::wait_for_all() {
41 42
  auto scheduler = thread_state::get()->scheduler_;

43
  while (ref_count_ > 0) {
44 45
    if (!scheduler->try_execute_local()) {
      scheduler->try_execute_stolen();
46 47
    }
  }
48
  thread_state::get()->deque_.reset_offset(deque_offset_);
49 50 51 52 53
}

}
}
}