
#ifndef PLS_LOCK_FREE_TASK_H_
#define PLS_LOCK_FREE_TASK_H_

#include "pls/internal/scheduling/base_task.h"
#include "pls/internal/data_structures/stamped_integer.h"
#include "pls/internal/scheduling/lock_free/traded_cas_field.h"

namespace pls::internal::scheduling::lock_free {

/**
 * Lock free task variant.
 * Needs extra fields to manage the trading and resources.
 * RELIES on the fact that tasks have a unique depth and thread id,
 * allowing to refer to a task solely by this property!
 */
struct task : public base_task {
  task(char *stack_memory, size_t stack_size, unsigned depth, unsigned thread_id) :
      base_task(stack_memory, stack_size, depth, thread_id) {}

  // Additional info for lock-free stealing and resource trading.
  std::atomic<traded_cas_field> external_trading_deque_cas_{};

  void push_task_chain(task *spare_task_chain);
  task *pop_task_chain();
  void reset_task_chain();

 private:
  std::atomic<base_task *> resource_stack_next_{};
  std::atomic<data_structures::stamped_integer> resource_stack_root_{{0, 0}};
};

}

#endif //PLS_LOCK_FREE_TASK_H_
