
#ifndef PLS_SCHEDULER_IMPL_H
#define PLS_SCHEDULER_IMPL_H

#include "pls/internal/scheduling/lambda_task.h"

namespace pls {
namespace internal {
namespace scheduling {

// TODO: generally look into the performance implications of using many thread_state::get() calls

template<typename Function>
void scheduler::perform_work(Function work_section) {
  PROFILE_WORK_BLOCK("scheduler::perform_work")

//  if (execute_main_thread) {
//    work_section();
//
//    sync_barrier_.wait(); // Trigger threads to wake up
//    sync_barrier_.wait(); // Wait for threads to finish
//  } else {
  lambda_task_by_reference<Function> root_task{work_section};
  main_thread_root_task_ = &root_task;
  work_section_done_ = false;

  sync_barrier_.wait(); // Trigger threads to wake up
  sync_barrier_.wait(); // Wait for threads to finish
//  }
}

template<typename T>
void scheduler::spawn_child(T &sub_task) {
  thread_state::get()->current_task_->spawn_child(sub_task);
}

template<typename T>
void scheduler::spawn_child_and_wait(T &sub_task) {
  thread_state::get()->current_task_->spawn_child_and_wait(sub_task);
}

}
}
}

#endif //PLS_SCHEDULER_IMPL_H
