diff --git a/src/shared/scheduler/TaskScheduler.cpp b/src/shared/scheduler/TaskScheduler.cpp index a071374d1aa8ba12b98881314fd6a76c1d3c339a..cb9d4107f71cabaa976c5cfcc04b89a7122b2933 100644 --- a/src/shared/scheduler/TaskScheduler.cpp +++ b/src/shared/scheduler/TaskScheduler.cpp @@ -35,40 +35,36 @@ namespace Boardcore TaskScheduler::TaskScheduler() : ActiveObject(STACK_MIN_FOR_SKYWARD, miosix::PRIORITY_MAX - 1) { - stopFlag = false; - running = false; - possibleFreeID = 1; + stopFlag = false; + running = false; } -uint8_t TaskScheduler::addTask(function_t function, uint32_t period, - Policy policy, int64_t startTick) +size_t TaskScheduler::addTask(function_t function, uint32_t period, + Policy policy, int64_t startTick) { Lock<FastMutex> lock(mutex); - uint8_t id = possibleFreeID; + size_t id = 1; // Find a suitable id for the new task - for (; id < 255 && tasks[id] != nullptr; ++id) + for (; id < TASKS_SIZE && tasks[id].valid == false; id++) ; - possibleFreeID = id + 1; // Check if in the corresponding id there's already a task - if (tasks[id] != nullptr) + if (tasks[id].valid) { - LOG_ERR(logger, "Full task scheduler, id = 255"); + LOG_ERR(logger, "Full task scheduler, id = {:zu}", id); return 0; } // Register the task into the map - Task* task = - new Task{function, period, id, true, policy, -1, {}, {}, {}, 0, 0}; - tasks[id] = task; + tasks[id] = makeTask(function, period, id, true, policy); if (policy == Policy::ONE_SHOT) startTick += period; // Add the task first event in the agenda - Event event = {task, startTick}; + Event event = {&(tasks[id]), startTick}; agenda.push(event); condvar.broadcast(); // Signals the run thread @@ -80,21 +76,14 @@ bool TaskScheduler::removeTask(uint8_t id) Lock<FastMutex> lock(mutex); // Check if the task is actually present - if (tasks[id] == nullptr) + if (tasks[id].valid == false) { LOG_ERR(logger, "Attempting to remove a task not registered"); return false; } // Set the validity of the task to false - tasks[id]->valid = false; - - // Remove the task from the tasks array - // We do not deallocate the task here because of future deallocation when - // popped from queue - tasks[id] = nullptr; - if (id < possibleFreeID) - possibleFreeID = id; + tasks[id].valid = false; return true; } @@ -128,7 +117,7 @@ vector<TaskStatsResult> TaskScheduler::getTaskStats() for (auto& task : tasks) { - if (task != nullptr) + if (task.valid) result.push_back(fromTaskIdPairToStatsResult(task)); } @@ -206,7 +195,6 @@ void TaskScheduler::run() { if (!nextEvent.task->valid) { - delete nextEvent.task; agenda.pop(); } @@ -248,9 +236,7 @@ void TaskScheduler::enqueue(Event& event, int64_t startTick) case Policy::ONE_SHOT: // If the task is one shot we won't push it to the agenda and we'll // remove it from the tasks map. - tasks[event.task->id] = nullptr; - if (event.task->id < possibleFreeID) - possibleFreeID = event.task->id; + tasks[event.task->id].valid = false; delete event.task; return; @@ -280,4 +266,11 @@ void TaskScheduler::enqueue(Event& event, int64_t startTick) condvar.broadcast(); } +TaskScheduler::Task TaskScheduler::makeTask(function_t function, + uint32_t period, size_t id, + bool validity, Policy policy) +{ + return Task{function, period, id, validity, policy, -1, {}, {}, {}, 0, 0}; +} + } // namespace Boardcore diff --git a/src/shared/scheduler/TaskScheduler.h b/src/shared/scheduler/TaskScheduler.h index daa18abdd1f52b0d6644b7f6287b5f792e5c5ad1..0efe40985e90d90fff586aadbb15f6fd85821f1b 100644 --- a/src/shared/scheduler/TaskScheduler.h +++ b/src/shared/scheduler/TaskScheduler.h @@ -61,6 +61,11 @@ class TaskScheduler : public ActiveObject public: typedef std::function<void()> function_t; + /** + * @brief It defines the tasks array maximum size + */ + static constexpr size_t TASKS_SIZE = 256; + /** * @brief Task behavior policy. * @@ -107,9 +112,9 @@ public: * @param startTick First activation time, useful for synchronizing tasks. * @return true if the task was added successfully. */ - uint8_t addTask(function_t function, uint32_t period, - Policy policy = Policy::SKIP, - int64_t startTick = miosix::getTick()); + size_t addTask(function_t function, uint32_t period, + Policy policy = Policy::SKIP, + int64_t startTick = miosix::getTick()); /** * @brief Removes the task identified by the given id if it exists. @@ -136,7 +141,7 @@ private: { function_t function; uint32_t period; - uint8_t id; + size_t id; bool valid; Policy policy; int64_t lastCall; ///< Last activation tick for statistics computation. @@ -186,23 +191,35 @@ private: */ void enqueue(Event& event, int64_t startTick); - static TaskStatsResult fromTaskIdPairToStatsResult(Task* task) + /** + * @brief Creates a task with the passed values + * + * @param function The std::function to be called + * @param period The Period in [ms] + * @param id The task intrinsic id + * @param validity The validity of the task (false if not initialized or if + * removed) + * @param policy The task policy in case of a miss + */ + Task makeTask(function_t function, uint32_t period, size_t id, + bool validity, Policy policy); + + static TaskStatsResult fromTaskIdPairToStatsResult(Task task) { - return TaskStatsResult{task->id, - task->period, - task->activationStats.getStats(), - task->periodStats.getStats(), - task->workloadStats.getStats(), - task->missedEvents, - task->failedEvents}; + return TaskStatsResult{task.id, + task.period, + task.activationStats.getStats(), + task.periodStats.getStats(), + task.workloadStats.getStats(), + task.missedEvents, + task.failedEvents}; } - miosix::FastMutex mutex; ///< Mutex to protect tasks and agenda. - std::array<Task*, 256> tasks{}; ///< Holds all tasks to be scheduled. - miosix::ConditionVariable condvar; ///< Used when agenda is empty. - std::priority_queue<Event> agenda; ///< Ordered list of functions. - uint8_t possibleFreeID; + miosix::FastMutex mutex; ///< Mutex to protect tasks and agenda. + std::array<Task, TASKS_SIZE> tasks{}; ///< Holds all tasks to be scheduled. + miosix::ConditionVariable condvar; ///< Used when agenda is empty. + std::priority_queue<Event> agenda; ///< Ordered list of functions. PrintLogger logger = Logging::getLogger("taskscheduler"); }; diff --git a/src/shared/scheduler/TaskSchedulerData.h b/src/shared/scheduler/TaskSchedulerData.h index f1c43d31f10ff54c1b2a6d26bf9932647a3a4769..8b612714a0f1bda9de9a29914a9f7d71560248c3 100644 --- a/src/shared/scheduler/TaskSchedulerData.h +++ b/src/shared/scheduler/TaskSchedulerData.h @@ -43,7 +43,7 @@ namespace Boardcore */ struct TaskStatsResult { - uint8_t id; + size_t id; uint32_t period; StatsResult activationStats; StatsResult periodStats;