
#ifndef PLS_ABSTRACT_TASK_H
#define PLS_ABSTRACT_TASK_H

#include "pls/internal/base/swmr_spin_lock.h"
#include "pls/internal/helpers/unique_id.h"

namespace pls {
namespace internal {
namespace scheduling {

class abstract_task {
 public:
  using id = helpers::unique_id;

 private:
  unsigned int depth_;
  abstract_task::id unique_id_;
  abstract_task *volatile child_task_;

 public:
  abstract_task(const unsigned int depth, const abstract_task::id &unique_id) :
      depth_{depth},
      unique_id_{unique_id},
      child_task_{nullptr} {}

  virtual void execute() = 0;
  void set_child(abstract_task *child_task) { child_task_ = child_task; }
  abstract_task *child() const { return child_task_; }

  void set_depth(unsigned int depth) { depth_ = depth; }
  unsigned int depth() const { return depth_; }
  id unique_id() const { return unique_id_; }
 protected:
  virtual bool internal_stealing(abstract_task *other_task) = 0;
  virtual bool split_task(base::swmr_spin_lock *lock) = 0;

  bool steal_work();
};

}
}
}

#endif //PLS_ABSTRACT_TASK_H
