118 lines
3.4 KiB
C++
118 lines
3.4 KiB
C++
#ifndef HYDRATASKSCHEDULER
|
|
#define HYDRATASKSCHEDULER
|
|
|
|
#include "../engine/HydraObject.h"
|
|
#include "HydraTaskBarrier.h"
|
|
#include "../task/HydraTask.h"
|
|
#include <vector>
|
|
#include <deque>
|
|
#include <mutex>
|
|
#include <queue>
|
|
#include <thread>
|
|
|
|
class HydraThread;
|
|
class HydraWorkItem;
|
|
// class HydraTask;
|
|
|
|
class CLASS_DEFINE HydraTaskScheduler : public HydraObject
|
|
{
|
|
private:
|
|
std::vector<HydraTaskBarrier *> m_barriers;
|
|
std::queue<HydraID> m_available_barrier_ids;
|
|
std::mutex m_mutex;
|
|
|
|
bool m_waiting = false;
|
|
bool m_running = true;
|
|
HydraID m_waiting_id = INVALID_HYDRA_ID;
|
|
std::vector<HydraThread *> m_general_thread;
|
|
|
|
HydraThread *m_render_thread = nullptr;
|
|
HydraThread *m_physics_thread = nullptr;
|
|
|
|
std::vector<HydraTask *> m_tasks;
|
|
std::vector<HydraID> m_task_ids_waiting_for_children;
|
|
|
|
std::deque<HydraID> m_avaialble_task_ids;
|
|
std::deque<HydraID> m_general_tasks_ready_to_run;
|
|
std::deque<HydraID> m_render_tasks_ready_to_run;
|
|
std::deque<HydraID> m_physics_tasks_ready_to_run;
|
|
|
|
HydraID _SaveTask(HydraTask *taskItem);
|
|
|
|
HydraID _GetRenderTaskReadyToRun();
|
|
HydraID _GetPhysicsTaskReadyToRun();
|
|
void _DecrementBarrier(HydraID taskID, HydraID barrierID);
|
|
void _UpdateDependantTaskComplete(HydraID taskID);
|
|
void _DeleteTask(HydraID taskID);
|
|
void _AddTaskToBarrier(HydraID taskID, HydraID barrierID);
|
|
void _StartTask(HydraID taskID, bool notifyThread = false);
|
|
void _NotifyThread(std::thread::id thread_id);
|
|
HydraID _CreateBarrier();
|
|
HydraTask *const _GetTask(HydraID taskID);
|
|
HydraID _GetTaskReadyToRun(HydraThreadAffinity thread_affinity);
|
|
void _CompleteBarrier(uint32_t barrierID);
|
|
protected:
|
|
public:
|
|
template <class T>
|
|
HydraID CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID);
|
|
template <class T>
|
|
HydraID CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID = INVALID_HYDRA_ID);
|
|
HydraTask *const GetTask(HydraID taskID);
|
|
void StartTask(HydraID taskID);
|
|
void WaitForTask(HydraID taskID);
|
|
HydraID CreateBarrier();
|
|
void AddTaskToBarrier(HydraID taskID, HydraID barrierID);
|
|
void WaitForBarrier(HydraID barrierID);
|
|
void DecrementBarrier(HydraID taskID, HydraID barrierID);
|
|
|
|
void Initialise(int thread_count);
|
|
void Shutdown();
|
|
|
|
void NotifyStart(HydraID taskID);
|
|
void NotifyComplete(HydraID taskID);
|
|
void ProcessTask();
|
|
|
|
void DeleteTask(HydraID taskID);
|
|
};
|
|
|
|
template <class T>
|
|
inline HydraID HydraTaskScheduler::CreateTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID)
|
|
{
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
T *taskType = new T();
|
|
HydraTask *task = dynamic_cast<HydraTask *>(taskType);
|
|
if (task != nullptr)
|
|
{
|
|
task->m_barrierID = barrierID;
|
|
task->ThreadAffinity = ThreadAffinity;
|
|
HydraID id = _SaveTask(task);
|
|
if (id != INVALID_HYDRA_ID)
|
|
{
|
|
_AddTaskToBarrier(id, barrierID);
|
|
}
|
|
else
|
|
{
|
|
delete taskType;
|
|
}
|
|
return id;
|
|
}
|
|
else
|
|
{
|
|
delete taskType;
|
|
return INVALID_HYDRA_ID;
|
|
}
|
|
};
|
|
template <class T>
|
|
inline HydraID HydraTaskScheduler::CreateAndStartTask(HydraThreadAffinity ThreadAffinity, HydraID barrierID)
|
|
{
|
|
|
|
HydraID taskID = CreateTask<T>(ThreadAffinity, barrierID);
|
|
if (taskID != INVALID_HYDRA_ID)
|
|
{
|
|
StartTask(taskID);
|
|
}
|
|
return taskID;
|
|
};
|
|
|
|
#endif /* HYDRATASKSCHEDULER */
|