#include // Define Task structure (simplified for memorization) typedef struct { int id; // Task ID int period; // Period (also deadline for simplicity) int execution_time; // Worst-case execution time (WCET) // --- Simulation State --- int remaining_execution; // Remaining execution time for current instance int absolute_deadline; // Absolute deadline for current instance int time_to_arrival; // Time until the next instance arrives/is released } Task; // --- Global Variables --- // Define the tasks for the simulation (Example Set) // Format: {id, Period, ExecutionTime, 0, 0, 0} <-- Initial state values Task tasks[] = { {1, 5, 2, 0, 0, 0}, // Task 1: Period=5, Exec Time=2 {2, 8, 3, 0, 0, 0} // Task 2: Period=8, Exec Time=3 // Add more tasks here if needed }; // Calculate number of tasks automatically int num_tasks = sizeof(tasks) / sizeof(Task); // Set simulation duration (e.g., Hyperperiod or a fixed time) // LCM(5, 8) = 40 int simulation_time = 40; // --- Rate Monotonic (RM) Simulation --- void simulate_rm() { printf("--- Rate Monotonic Scheduling ---\n"); // Reset task states for the simulation run for (int i = 0; i < num_tasks; i++) { tasks[i].remaining_execution = 0; tasks[i].absolute_deadline = 0; tasks[i].time_to_arrival = 0; // All tasks start at time 0 } // Main simulation loop for (int time = 0; time < simulation_time; time++) { // 1. Check for task arrivals (release time) for (int i = 0; i < num_tasks; i++) { if (tasks[i].time_to_arrival == 0) { // Check if the previous instance of this task missed its deadline if (tasks[i].remaining_execution > 0) { printf("!!! Time %d: Task %d MISSED DEADLINE !!!\n", time, tasks[i].id); // Simple handling: Continue with the new instance, old one is lost } // Release new instance of the task tasks[i].remaining_execution = tasks[i].execution_time; tasks[i].absolute_deadline = time + tasks[i].period; // Deadline = Period tasks[i].time_to_arrival = tasks[i].period; // Set timer for the *next* arrival } tasks[i].time_to_arrival--; // Decrement time until the next arrival for all tasks } // 2. Select highest priority task to run (RM: Shortest Period has highest priority) int task_to_run = -1; // -1 indicates CPU Idle int highest_priority = 10000; // Initialize with a low priority (large period) for (int i = 0; i < num_tasks; i++) { // Check if task is ready (has arrived and needs execution) if (tasks[i].remaining_execution > 0) { // RM priority check: Lower period value means higher priority if (tasks[i].period < highest_priority) { highest_priority = tasks[i].period; task_to_run = i; // Select this task } } } // 3. Execute the selected task (or remain idle) if (task_to_run != -1) { // Task selected to run printf("Time %d: Task %d running\n", time, tasks[task_to_run].id); tasks[task_to_run].remaining_execution--; // Execute for one time unit // Optional: Check if task just finished // if (tasks[task_to_run].remaining_execution == 0) { // printf("Time %d: Task %d finished\n", time + 1, tasks[task_to_run].id); // } } else { // No task ready to run printf("Time %d: CPU Idle\n", time); } } printf("--- RM Simulation Complete ---\n"); } // --- Earliest Deadline First (EDF) Simulation --- void simulate_edf() { printf("\n--- Earliest Deadline First Scheduling ---\n"); // Reset task states for (int i = 0; i < num_tasks; i++) { tasks[i].remaining_execution = 0; tasks[i].absolute_deadline = 0; tasks[i].time_to_arrival = 0; } // Main simulation loop for (int time = 0; time < simulation_time; time++) { // 1. Check for task arrivals (same as RM) for (int i = 0; i < num_tasks; i++) { if (tasks[i].time_to_arrival == 0) { if (tasks[i].remaining_execution > 0) { printf("!!! Time %d: Task %d MISSED DEADLINE !!!\n", time, tasks[i].id); } tasks[i].remaining_execution = tasks[i].execution_time; tasks[i].absolute_deadline = time + tasks[i].period; tasks[i].time_to_arrival = tasks[i].period; } tasks[i].time_to_arrival--; } // 2. Select highest priority task to run (EDF: Earliest Absolute Deadline has highest priority) int task_to_run = -1; int earliest_deadline = 10000; // Initialize with a late deadline for (int i = 0; i < num_tasks; i++) { // Check if task is ready if (tasks[i].remaining_execution > 0) { // EDF priority check: Lower deadline value means higher priority (earlier deadline) if (tasks[i].absolute_deadline < earliest_deadline) { earliest_deadline = tasks[i].absolute_deadline; task_to_run = i; // Select this task } } } // 3. Execute the selected task (same as RM) if (task_to_run != -1) { printf("Time %d: Task %d running\n", time, tasks[task_to_run].id); tasks[task_to_run].remaining_execution--; // Optional: Check finish // if (tasks[task_to_run].remaining_execution == 0) { // printf("Time %d: Task %d finished\n", time + 1, tasks[task_to_run].id); // } } else { printf("Time %d: CPU Idle\n", time); } } printf("--- EDF Simulation Complete ---\n"); } // --- Main Function --- int main() { // Run Rate Monotonic simulation simulate_rm(); // Run Earliest Deadline First simulation simulate_edf(); return 0; // Indicate successful execution }