diff --git a/Exercises/Response-Time Analysis/.vscode/launch.json b/Exercises/Response-Time Analysis/.vscode/launch.json index 6211b38..474e99b 100644 --- a/Exercises/Response-Time Analysis/.vscode/launch.json +++ b/Exercises/Response-Time Analysis/.vscode/launch.json @@ -5,7 +5,7 @@ "name": "Debug C++", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/real_time_analysis", + "program": "${workspaceFolder}/build/response_time_analysis", "args": ["${workspaceFolder}/exercise-TC2.csv"], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/Exercises/Response-Time Analysis/.vscode/tasks.json b/Exercises/Response-Time Analysis/.vscode/tasks.json index 3f864fb..956cd19 100644 --- a/Exercises/Response-Time Analysis/.vscode/tasks.json +++ b/Exercises/Response-Time Analysis/.vscode/tasks.json @@ -7,9 +7,9 @@ "command": "g++", "args": [ "-g", - "${workspaceFolder}/src/real_time_analysis.cpp", + "${workspaceFolder}/src/response_time_analysis.cpp", "-o", - "${workspaceFolder}/build/real_time_analysis" + "${workspaceFolder}/build/response_time_analysis" ], "group": { "kind": "build", diff --git a/Exercises/Response-Time Analysis/build/real_time_analysis b/Exercises/Response-Time Analysis/build/response_time_analysis old mode 100644 new mode 100755 similarity index 54% rename from Exercises/Response-Time Analysis/build/real_time_analysis rename to Exercises/Response-Time Analysis/build/response_time_analysis index 9013645..c819722 Binary files a/Exercises/Response-Time Analysis/build/real_time_analysis and b/Exercises/Response-Time Analysis/build/response_time_analysis differ diff --git a/Exercises/Response-Time Analysis/src/real_time_analysis.cpp b/Exercises/Response-Time Analysis/src/response_time_analysis.cpp similarity index 77% rename from Exercises/Response-Time Analysis/src/real_time_analysis.cpp rename to Exercises/Response-Time Analysis/src/response_time_analysis.cpp index fbb2d2a..f3e0315 100644 --- a/Exercises/Response-Time Analysis/src/real_time_analysis.cpp +++ b/Exercises/Response-Time Analysis/src/response_time_analysis.cpp @@ -36,10 +36,10 @@ void readTasksCSV(const string& filename, vector& tasks) getline(ss, token, ','); // Task ID task.id = token; - getline(ss, token, ','); // WCET - task.WCET = stoi(token); getline(ss, token, ','); // BCET task.BCET = stoi(token); + getline(ss, token, ','); // WCET + task.WCET = stoi(token); getline(ss, token, ','); // Period task.period = stoi(token); getline(ss, token, ','); // Deadline @@ -56,31 +56,28 @@ void RTA_test(vector& tasks) { // Sort tasks by priority (lower number means higher priority) sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) { - return a.priority < b.priority; // Ensure lower priority number = higher priority + return a.priority < b.priority; }); - for (size_t task = 0; task < tasks.size(); task++) + for (size_t i = 0; i < tasks.size(); i++) { - int R = tasks[task].WCET; + int R = tasks[i].WCET; int last_R = -1; bool schedulable = true; - int I = 0; // Reset interference for each iteration while (R != last_R) { last_R = R; - - // Compute interference from higher-priority tasks - for (size_t j = 0; j < task; j++) + int I = 0; + for (size_t j = 0; j < i; j++) { I += ceil((double)R / tasks[j].period) * tasks[j].WCET; } + R = tasks[i].WCET + I; - R = I + tasks[task].WCET; - - if (R > tasks[task].deadline) + if (R > tasks[i].deadline) { - cout << "Task " << tasks[task].id << " is not schedulable." << endl; + cout << "Task " << tasks[i].id << " is not schedulable with WCRT." << endl; schedulable = false; break; } @@ -88,11 +85,12 @@ void RTA_test(vector& tasks) if (schedulable) { - cout << "Task " << tasks[task].id << " is schedulable with WCRT = " << R << endl; + cout << "Task " << tasks[i].id << " is schedulable with WCRT = " << R << endl; } } } + int main(int argc, char* argv[]) { if (argc != 2) { @@ -107,4 +105,4 @@ int main(int argc, char* argv[]) RTA_test(tasks); return 0; -} \ No newline at end of file +} diff --git a/Exercises/Very Simple Simulator/build/very_simple_simulator b/Exercises/Very Simple Simulator/build/very_simple_simulator old mode 100644 new mode 100755 index e41076a..12e9167 Binary files a/Exercises/Very Simple Simulator/build/very_simple_simulator and b/Exercises/Very Simple Simulator/build/very_simple_simulator differ diff --git a/Exercises/Very Simple Simulator/src/very_simple_simulator.cpp b/Exercises/Very Simple Simulator/src/very_simple_simulator.cpp index 399bd1e..d250a83 100644 --- a/Exercises/Very Simple Simulator/src/very_simple_simulator.cpp +++ b/Exercises/Very Simple Simulator/src/very_simple_simulator.cpp @@ -13,7 +13,7 @@ struct Task { int WCET; int period; int deadline; - int priority; // Lower number => higher priority for RMS, if you wish + int priority; // Lower number => higher priority for RMS }; // Define the Job structure @@ -45,10 +45,10 @@ void readTasksCSV(const string& filename, vector& tasks) getline(ss, token, ','); // Task ID task.id = token; - getline(ss, token, ','); // WCET - task.WCET = stoi(token); getline(ss, token, ','); // BCET task.BCET = stoi(token); + getline(ss, token, ','); // WCET + task.WCET = stoi(token); getline(ss, token, ','); // Period task.period = stoi(token); getline(ss, token, ','); // Deadline @@ -59,22 +59,20 @@ void readTasksCSV(const string& filename, vector& tasks) tasks.push_back(task); } file.close(); -} -// Function to check if all jobs are completed -bool allJobsCompleted(const vector& jobs) -{ - for (const auto& job : jobs) { - if (job.remainingTime > 0) { - return false; - } - } - return true; + sort(tasks.begin(), tasks.end(), [](const Task& a, const Task& b) { + return a.id < b.id; + }); } // Function to find the job with the highest priority Job *highest_priority(vector& readyList) { + if (readyList.empty()) + { + return nullptr; + } + return *min_element( readyList.begin(), readyList.end(), @@ -96,9 +94,15 @@ vector get_ready(vector& jobs, int currentTime) return readyList; } +int advanceTime() +{ + return 1; +} + int main(int argc, char* argv[]) { - if (argc != 2) { + if (argc != 2) + { cerr << "Usage: " << argv[0] << " " << endl; return 1; } @@ -107,75 +111,81 @@ int main(int argc, char* argv[]) vector tasks; readTasksCSV(filename, tasks); + // Simulation time (n cycles) int n = 1000; int currentTime = 0; + // List of all jobs that are in the system vector jobs; - jobs.reserve(tasks.size()); - for (const auto& t : tasks) { - jobs.push_back({t, 0, t.WCET, 0}); - } + // Initialize next release time for each task (all tasks start at time 0) + vector nextReleaseTimes(tasks.size(), 0); + + // We also maintain worst-case response times (WCRT) for each task. vector worstCaseResponseTimes(tasks.size(), 0); - while (currentTime < n && !allJobsCompleted(jobs)) + // Simulation loop + while (currentTime <= n) { - // Release new jobs at the start of each period - for (const auto& t : tasks) + // For each task, if it is time to release a new job, create it. + for (size_t i = 0; i < tasks.size(); ++i) { - if (currentTime != 0 && currentTime % t.period == 0) { - jobs.push_back({t, currentTime, t.WCET, 0}); + if (currentTime >= nextReleaseTimes[i]) + { + Job newJob { tasks[i], currentTime, tasks[i].WCET, 0 }; + jobs.push_back(newJob); + nextReleaseTimes[i] += tasks[i].period; } } - - // Get the list of ready jobs + vector readyList = get_ready(jobs, currentTime); - - // If no jobs are ready, increment the current time - if (readyList.empty()) - { - currentTime++; - continue; - } - - // Get the job with the highest priority Job* currentJob = highest_priority(readyList); if (currentJob != nullptr) { - // Execute the job for one time unit - currentJob->remainingTime--; - currentTime++; - - // If the job is completed, update its response time + int delta = advanceTime(); + currentTime += delta; + currentJob->remainingTime -= delta; + + // If the job has completed execution, calculate its response time and update WCRT if (currentJob->remainingTime <= 0) { currentJob->responseTime = currentTime - currentJob->releaseTime; - int taskIndex = distance( - tasks.begin(), - find_if(tasks.begin(), tasks.end(), [&](const Task& tk){ - return tk.id == currentJob->task.id; - }) - ); - worstCaseResponseTimes[taskIndex] = max( - worstCaseResponseTimes[taskIndex], - currentJob->responseTime - ); + + // Find the corresponding task index + auto it = find_if(tasks.begin(), tasks.end(), [&](const Task& t) { + return t.id == currentJob->task.id; + }); + + if (it != tasks.end()) + { + size_t taskIndex = distance(tasks.begin(), it); + worstCaseResponseTimes[taskIndex] = max( + worstCaseResponseTimes[taskIndex], + currentJob->responseTime + ); + } } } else { - currentJob->remainingTime--; - currentTime++; + // If no job is ready, just advance time + int delta = advanceTime(); + currentTime += delta; } } // Output the worst-case response times for each task + cout << "Task\tWCRT\tDeadline\tStatus" << endl; + cout << "---------------------------------" << endl; for (size_t i = 0; i < tasks.size(); ++i) { - cout << "Task " << tasks[i].id - << " WCRT: " << worstCaseResponseTimes[i] << endl; + string status = (worstCaseResponseTimes[i] <= tasks[i].deadline) ? "✓" : "✗"; + cout << " " << tasks[i].id << "\t" + << worstCaseResponseTimes[i] << "\t" + << tasks[i].deadline << "\t\t" + << status << endl; } return 0; -} \ No newline at end of file +}