diff --git a/include/Task.h b/include/Task.h index 27e6af2..adead0f 100644 --- a/include/Task.h +++ b/include/Task.h @@ -3,32 +3,99 @@ namespace e2e { +/** + * @struct Task + * @brief Represents a task with its execution parameters. + * + * A `Task` is a core unit of scheduling. It contains information about the task's + * period, worst-case response time (WCRT), priority, and an optional offset. + * + * Tasks are used to describe periodic tasks in a real-time system, where each task + * has a period (time between executions), a WCRT (maximum time it takes to complete), + * a priority (used for scheduling), and an offset (delays the first execution). + */ struct Task { - int period; - int wcrt; - int priority; - int offset = 0; + int period; // The period of the task (in time units). + int wcrt; // The worst-case response time (in time units). + int priority; // The priority of the task (higher value means higher priority). + int offset = 0; // The offset (initial delay before task execution), default is 0. + /** + * @brief Constructs a Task with a specified period, WCRT, and priority. + * @param period The period of the task. + * @param wcrt The worst-case response time of the task. + * @param priority The priority of the task. + */ Task(int period, int wcrt, int priority) : period(period), wcrt(wcrt), priority(priority) {} + /** + * @brief Constructs a Task with a specified period, WCRT, priority, and offset. + * @param period The period of the task. + * @param wcrt The worst-case response time of the task. + * @param priority The priority of the task. + * @param offset The offset (initial delay) for the task. + */ Task(int period, int wcrt, int priority, int offset) : period(period), wcrt(wcrt), priority(priority), offset(offset) {} + /** + * @brief Equality operator for comparing two Task objects. + * @param other The task to compare with. + * @return True if the tasks are equal, false otherwise. + */ bool operator==(const Task& other) const; + + /** + * @brief Inequality operator for comparing two Task objects. + * @param other The task to compare with. + * @return True if the tasks are not equal, false otherwise. + */ bool operator!=(const Task& other) const; }; +/** + * @struct TaskInstance + * @brief Represents an instance of a task in time. + * + * A `TaskInstance` extends a `Task` by adding an activation time that specifies when + * the task should be executed. Each `TaskInstance` represents a specific execution + * of a task, occurring at a specific point in time. + */ struct TaskInstance { - Task baseTask; - int activationTime; + Task baseTask; // The base task, which contains the task's period, WCRT, priority, and offset. + int activationTime; // The time at which this task instance is activated. + /** + * @brief Constructs a TaskInstance with a base task and an activation time. + * @param baseTask The base task object representing the task. + * @param activationTime The activation time of this task instance. + */ TaskInstance(const Task& baseTask, int activationTime) : baseTask(baseTask), activationTime(activationTime) {} + /** + * @brief Gets the next instance of the task. + * + * The next task instance is calculated based on the period of the base task + * and the current instance's activation time. + * + * @return The next `TaskInstance` based on the current one. + */ TaskInstance nextInstance() const; + /** + * @brief Equality operator for comparing two TaskInstance objects. + * @param other The task instance to compare with. + * @return True if the task instances are equal, false otherwise. + */ bool operator==(const TaskInstance& other) const; + + /** + * @brief Inequality operator for comparing two TaskInstance objects. + * @param other The task instance to compare with. + * @return True if the task instances are not equal, false otherwise. + */ bool operator!=(const TaskInstance& other) const; }; diff --git a/include/TaskScheduling.h b/include/TaskScheduling.h index bf30e66..a6b3f03 100644 --- a/include/TaskScheduling.h +++ b/include/TaskScheduling.h @@ -10,18 +10,75 @@ namespace e2e { namespace scheduling { +/** + * @brief Calculates the least common multiple (LCM) for a task path. + * + * This function computes the least common multiple (LCM) of the periods of all the tasks + * in the provided task path. The LCM is useful in scheduling algorithms, particularly for + * determining the interval after which the tasks will repeat their execution. + * + * @param taskPath A vector of tasks representing the task path. + * + * @return The least common multiple of the periods of the tasks in the path. + */ int calculateLcmForEndToEndPath(const std::vector& endToEndPath); -std::vector> generateTaskInstancesFromTasks( - const std::vector& endToEndPath); +/** + * @brief Generates task instances from a task path. + * + * This function generates task instances for each task in the provided task path. Each + * task instance has a specific activation time based on the task's period and offset. + * + * @param taskPath A vector of tasks that define the task path. + * + * @return A vector of vectors, where each inner vector contains task instances for + * each task in the path. + */ +std::vector> generateTaskInstancesFromPath( + const std::vector& taskPath); -std::set generateTimedPaths( +/** + * @brief Generates timed paths from task instances. + * + * This function takes a set of task instance chains and generates corresponding timed + * paths. A timed path is a sequence of task instances with their activation times. + * + * @param taskInstanceChains A vector of vectors of task instances. + * + * @return A set of timed paths, where each path is a sequence of task instances with + * specific activation times. + */ +std::set generateTimedPathsFromInstances( const std::vector>& taskInstanceChains); -std::vector> buildTimedPaths( +/** + * @brief Builds execution paths from task instance chains. + * + * This function constructs execution paths by chaining together task instances based + * on the provided task instance chains. The result is a set of paths that represent + * the execution order of tasks over time. + * + * @param taskInstanceChains A vector of vectors of task instances. + * + * @return A vector of vectors, each representing an execution path of task instances. + */ +std::vector> buildTaskExecutionPaths( const std::vector>& taskInstanceChains); -std::vector> pathCartesianProduct( +/** + * @brief Computes the Cartesian product of timed paths. + * + * This function calculates the Cartesian product of the provided timed paths with + * a specific task instance chain, generating all possible combinations of timed + * paths from both inputs. + * + * @param timedPaths A vector of vectors of task instances, representing the timed paths. + * @param taskInstanceChain A vector of task instances to combine with the timed paths. + * + * @return A vector of vectors, where each inner vector represents a combination of + * timed paths and task instances from the input. + */ +std::vector> cartesianProductOfTimedPaths( const std::vector>& timedPaths, const std::vector& taskInstanceChain); diff --git a/include/TimedPath.h b/include/TimedPath.h index 6a7b28c..96ec2b3 100644 --- a/include/TimedPath.h +++ b/include/TimedPath.h @@ -57,12 +57,46 @@ class TimedPath { */ const std::vector& asVector() const; + /** + * @brief Returns the activation time of the first task in the timed path. + * + * This function calculates the activation time of the first task in the path + * by returning the activation time of the first task instance. + * + * @return The activation time of the first task in the timed path. + */ int firstTaskActivationTime() const; + /** + * @brief Returns the activation time of the last task in the timed path. + * + * This function calculates the activation time of the last task in the path + * by returning the activation time of the last task instance. + * + * @return The activation time of the last task in the timed path. + */ int lastTaskActivationTime() const; + /** + * @brief Checks if the current timed path succeeds the given timed path. + * + * This function checks if the current timed path starts after the other timed + * path finishes, making the current path a successor in terms of activation time. + * + * @param other The other TimedPath to compare with. + * @return true if the current path succeeds the other path, false otherwise. + */ bool succeeds(const TimedPath& other) const; + /** + * @brief Calculates the period of the timed path. + * + * This function computes the period of the timed path, which is the time it + * takes for the path to repeat its execution. It’s calculated as the difference + * between the activation times of the first and last tasks in the path. + * + * @return The period of the timed path. + */ int calculatePathPeriod() const; /** @@ -86,6 +120,15 @@ class TimedPath { */ bool operator==(const TimedPath& other) const; + /** + * @brief Compare two TimedPath objects for inequality. + * + * This function checks if two TimedPath objects are not equal by comparing + * their names. + * + * @param other The TimedPath object to compare with. + * @return true if the TimedPath objects have different names, false otherwise. + */ bool operator!=(const TimedPath& other) const; private: diff --git a/include/io/logger/ILogger.h b/include/io/logger/ILogger.h index b35061c..403a93b 100644 --- a/include/io/logger/ILogger.h +++ b/include/io/logger/ILogger.h @@ -9,26 +9,84 @@ namespace e2e { namespace io { +/** + * @brief Interface for logging various timed path results. + * + * The ILogger interface defines methods for logging the results related to + * timed paths, including valid/invalid paths, maximum latency, and path delays. + * This interface is intended to be implemented by concrete logger classes that + * handle different logging mechanisms (e.g., console logging, file logging). + */ class ILogger { public: + /** + * @brief Logs the valid and invalid paths. + * + * This function logs the entire set of paths, along with separate logs for + * valid and invalid paths. It helps in analyzing the correctness of the paths. + * + * @param allPathsSet A set containing all the timed paths. + * @param validPathSet A set containing valid timed paths. + * @param invalidPathSet A set containing invalid timed paths. + */ virtual void logValidInvalidPaths( const std::set& allPathsSet, const std::set& validPathSet, const std::set& invalidPathSet) const = 0; + /** + * @brief Logs the results of maximum latency path calculation (LL). + * + * This function logs the path with the maximum latency, where latency is + * typically defined as the time delay from start to end of the path. + * + * @param maximumLatencyPath An optional TimedPath representing the path + * with the maximum latency. + */ virtual void logResults_LL( const std::optional& maximumLatencyPath) const = 0; + /** + * @brief Logs the results of latency from first to last task (LF). + * + * This function logs the maximum latency path from the first task to + * the last task in the timed path. + * + * @param maximumLatencyPath An optional TimedPath representing the + * path with the maximum latency. + */ virtual void logResults_LF( const std::optional& maximumLatencyPath) const = 0; + /** + * @brief Logs the results of the maximum first-to-last path delay. + * + * This function logs the maximum delay between the first and last + * task instances in a timed path. + * + * @param maxFirstToLastPathDelay The maximum first-to-last path delay. + */ virtual void logResults_FL(int maxFirstToLastPathDelay) const = 0; + /** + * @brief Logs the results of the maximum first-to-first path delay. + * + * This function logs the maximum delay between the first task instance + * of the path and the first task instance of the next cycle. + * + * @param maxFirstToFirstPathDelay The maximum first-to-first path delay. + */ virtual void logResults_FF(int maxFirstToFirstPathDelay) const = 0; + /** + * @brief Virtual destructor for the logger. + * + * This virtual destructor ensures proper cleanup of any derived classes. + */ virtual ~ILogger() = default; }; + } // namespace io } // namespace e2e diff --git a/include/io/reader/ITaskInstanceReader.h b/include/io/reader/ITaskInstanceReader.h index 4b1f66f..9e8fa40 100644 --- a/include/io/reader/ITaskInstanceReader.h +++ b/include/io/reader/ITaskInstanceReader.h @@ -9,12 +9,37 @@ namespace e2e { namespace io { +/** + * @brief Interface for reading task instance paths. + * + * The ITaskInstanceReader interface defines a method for reading a set of + * timed paths, where each path represents a sequence of task instances + * associated with specific timing information. This allows different + * implementations to read paths from various sources (e.g., files, databases). + */ class ITaskInstanceReader { public: + /** + * @brief Reads a set of timed paths. + * + * This method returns a set of `TimedPath` objects, where each `TimedPath` + * contains a sequence of task instances. The set ensures that each path + * is unique within the collection. + * + * @return A set of timed paths, where each path represents a valid sequence + * of task instances. + */ virtual std::set readPathsSet() const = 0; + + /** + * @brief Virtual destructor for the task instance reader. + * + * This virtual destructor ensures proper cleanup of any derived classes. + */ virtual ~ITaskInstanceReader() = default; }; + } // namespace io } // namespace e2e diff --git a/include/io/reader/ITaskReader.h b/include/io/reader/ITaskReader.h index 40afa4f..dcafcb6 100644 --- a/include/io/reader/ITaskReader.h +++ b/include/io/reader/ITaskReader.h @@ -11,20 +11,59 @@ namespace io { struct NamedTask; +/** + * @brief Interface for reading a chain of named tasks. + * + * The ITaskReader interface defines a method for reading a sequence (chain) + * of tasks where each task is associated with a name. This interface allows + * the implementation of different task reading mechanisms (e.g., reading from a + * file, database, or another source). + */ class ITaskReader { public: + /** + * @brief Reads a chain of named tasks. + * + * This method returns a vector of `NamedTask` objects, where each `NamedTask` + * consists of a `Task` and its corresponding name. It represents a sequence + * of tasks to be executed in a certain order. + * + * @return A vector containing the named tasks in the chain. + */ virtual std::vector readTaskChain() const = 0; + + /** + * @brief Virtual destructor for the task reader. + * + * This virtual destructor ensures proper cleanup of any derived classes. + */ virtual ~ITaskReader() = default; }; +/** + * @brief A struct representing a task with an associated name. + * + * The `NamedTask` struct combines a `Task` object with a name. The name helps + * in identifying or labeling the task, which could be useful for logging, debugging, + * or task management. + */ struct NamedTask { - Task task; - std::string name; + Task task; // The task object that contains task-specific data like period, latency, etc. + std::string name; // The name associated with the task. + /** + * @brief Constructs a NamedTask object. + * + * Initializes a NamedTask with a specific task and its associated name. + * + * @param task The Task object representing the task's properties. + * @param name The name associated with the task. + */ NamedTask(const Task& task, const std::string& name) : task(task), name(name) {} }; + } // namespace io } // namespace e2e diff --git a/source/TaskScheduling.cpp b/source/TaskScheduling.cpp index cfeabaa..4476cab 100644 --- a/source/TaskScheduling.cpp +++ b/source/TaskScheduling.cpp @@ -19,7 +19,7 @@ int scheduling::calculateLcmForEndToEndPath( } std::vector> -scheduling::generateTaskInstancesFromTasks( +scheduling::generateTaskInstancesFromPath( const std::vector& endToEndPath) { if (endToEndPath.empty()) { return std::vector>(); @@ -43,7 +43,7 @@ scheduling::generateTaskInstancesFromTasks( return result; } -std::set scheduling::generateTimedPaths( +std::set scheduling::generateTimedPathsFromInstances( const std::vector>& timedPaths) { std::set result; if (timedPaths.empty()) { @@ -60,19 +60,19 @@ std::set scheduling::generateTimedPaths( return result; } -std::vector> scheduling::buildTimedPaths( +std::vector> scheduling::buildTaskExecutionPaths( const std::vector>& taskInstanceChains) { std::vector> timedPaths; for (const auto& taskInstanceChain : taskInstanceChains) { timedPaths = - scheduling::pathCartesianProduct(timedPaths, taskInstanceChain); + scheduling::cartesianProductOfTimedPaths(timedPaths, taskInstanceChain); } return timedPaths; } -std::vector> scheduling::pathCartesianProduct( +std::vector> scheduling::cartesianProductOfTimedPaths( const std::vector>& timedPaths, const std::vector& taskInstanceChain) { std::vector> product; diff --git a/source/executable/main_Tasks.cpp b/source/executable/main_Tasks.cpp index 11c60d5..834f74e 100644 --- a/source/executable/main_Tasks.cpp +++ b/source/executable/main_Tasks.cpp @@ -65,13 +65,13 @@ int main(int argc, char* argv[]) { } std::vector> taskInstances = - scheduling::generateTaskInstancesFromTasks(taskChain); + scheduling::generateTaskInstancesFromPath(taskChain); std::vector> allPossiblePaths = - scheduling::buildTimedPaths(taskInstances); + scheduling::buildTaskExecutionPaths(taskInstances); std::set pathSet = - scheduling::generateTimedPaths(allPossiblePaths); + scheduling::generateTimedPathsFromInstances(allPossiblePaths); // perform the analysis std::set validPathSet_LL = diff --git a/tests/TaskSchedulingTests.cpp b/tests/TaskSchedulingTests.cpp index 8076a11..0d4e79f 100644 --- a/tests/TaskSchedulingTests.cpp +++ b/tests/TaskSchedulingTests.cpp @@ -35,7 +35,7 @@ TEST(TaskScheduling, CorrectLcmForSeveralTasks) { TEST(TaskScheduling, EmptyTaskChainReturnsEmptyTaskInstanceChain) { std::vector> actual = - scheduling::generateTaskInstancesFromTasks({}); + scheduling::generateTaskInstancesFromPath({}); EXPECT_TRUE(actual.empty()); } @@ -46,7 +46,7 @@ TEST(TaskScheduling, std::vector> expected = {{TaskInstance(t1, 0)}}; std::vector> actual = - scheduling::generateTaskInstancesFromTasks({t1}); + scheduling::generateTaskInstancesFromPath({t1}); EXPECT_EQ(expected, actual); } @@ -67,7 +67,7 @@ TEST(TaskScheduling, CorrectInstanceChainsForSeveralTasks) { TaskInstance(t3, 36)}}; std::vector> actual = - scheduling::generateTaskInstancesFromTasks(tasks); + scheduling::generateTaskInstancesFromPath(tasks); EXPECT_EQ(expected, actual); } @@ -88,13 +88,13 @@ TEST(TaskScheduling, CorrectInstanceChainsForSeveralTasksWithOffsets) { TaskInstance(t3, 41)}}; std::vector> actual = - scheduling::generateTaskInstancesFromTasks(tasks); + scheduling::generateTaskInstancesFromPath(tasks); EXPECT_EQ(expected, actual); } TEST(TaskScheduling, EmptyTaskChainReturnsEmptySet) { - std::set actual = scheduling::generateTimedPaths({}); + std::set actual = scheduling::generateTimedPathsFromInstances({}); EXPECT_TRUE(actual.empty()); } @@ -110,7 +110,7 @@ TEST(TaskScheduling, TaskChainWithOneInstanceChain) { std::set expected = {onlyPossiblePath}; std::set actual = - scheduling::generateTimedPaths(taskInstanceChain); + scheduling::generateTimedPathsFromInstances(taskInstanceChain); EXPECT_EQ(expected, actual); } @@ -128,9 +128,9 @@ TEST(TaskScheduling, TaskChainWithOneTaskReturnsSetWithPathContainingOneTask) { std::set expected = {tp1, tp2, tp3}; std::vector> possiblePaths = - scheduling::buildTimedPaths(taskInstanceChain); + scheduling::buildTaskExecutionPaths(taskInstanceChain); - std::set actual = scheduling::generateTimedPaths(possiblePaths); + std::set actual = scheduling::generateTimedPathsFromInstances(possiblePaths); EXPECT_EQ(expected, actual); } @@ -165,10 +165,10 @@ TEST(TaskScheduling, CanBuildTaskChain) { {TaskInstance(t1, 20), TaskInstance(t2, 0), TaskInstance(t3, 36)}}; std::vector> taskInstances = - scheduling::generateTaskInstancesFromTasks(tasks); + scheduling::generateTaskInstancesFromPath(tasks); std::vector> actual = - scheduling::buildTimedPaths(taskInstances); + scheduling::buildTaskExecutionPaths(taskInstances); EXPECT_EQ(expected, actual); } @@ -211,13 +211,13 @@ TEST(TaskScheduling, CanCreateTimedPathSet) { } std::vector> taskInstances = - scheduling::generateTaskInstancesFromTasks(tasks); + scheduling::generateTaskInstancesFromPath(tasks); std::vector> actualPossiblePaths = - scheduling::buildTimedPaths(taskInstances); + scheduling::buildTaskExecutionPaths(taskInstances); std::set actual = - scheduling::generateTimedPaths(actualPossiblePaths); + scheduling::generateTimedPathsFromInstances(actualPossiblePaths); EXPECT_EQ(expected, actual); } @@ -233,13 +233,13 @@ TEST(TaskScheduling, CanCreateTimedPathSetForMoreComplexTasks) { std::size_t expected = 864; std::vector> taskInstances = - scheduling::generateTaskInstancesFromTasks(tasks); + scheduling::generateTaskInstancesFromPath(tasks); std::vector> actualPossiblePaths = - scheduling::buildTimedPaths(taskInstances); + scheduling::buildTaskExecutionPaths(taskInstances); std::set actual = - scheduling::generateTimedPaths(actualPossiblePaths); + scheduling::generateTimedPathsFromInstances(actualPossiblePaths); EXPECT_EQ(expected, actual.size()); } \ No newline at end of file