diff --git a/OS/C/Week8/aq1.c b/OS/C/Week8/aq1.c index 8b4318b..0bb16df 100644 --- a/OS/C/Week8/aq1.c +++ b/OS/C/Week8/aq1.c @@ -1,10 +1,11 @@ +{{REWRITTEN_CODE}} #include -// C program for Banker's Algorithm (Safety & Resource Request) +// C program for Banker's Algorithm (Safety & Resource Request Loop) // Optimized for minimal code size (e.g., for writing on paper) int main() { - int p, r, i, j, k, pid, req_pid = -1; // p=procs, r=res; req_pid: -1=initial, >=0 processing req + int p, r, i, j, k, pid, req_pid = -1; // req_pid: -1=initial/between reqs, >=0 processing req printf("P R:"); scanf("%d%d", &p, &r); // Input num processes and resources int av[r], max[p][r], al[p][r], nd[p][r], req[r]; // av=avail, al=alloc, nd=need int w[r], fin[p], seq[p]; // w=work, fin=finish, seq=safe sequence @@ -40,38 +41,53 @@ S:; // Safety Check Algorithm Label // --- End Safety Check --- - // Handle result based on phase (initial check or request check) - if(req_pid == -1) { // Phase 1: Initial State Check - if(safe) { - printf("SAFE. Seq:"); for(i=0; i nd[pid][j]) { puts("Err:Req>Need"); goto end; } - // Check 2: Request <= Available - for(j=0; j av[j]) { puts("Wait:Req>Avail"); goto end; } - - // Tentatively allocate resources - for(j=0; j= p check if needed + if (pid >= p) { puts("Invalid PID."); goto R;} + + printf("Req:"); for(j=0; j nd[pid][j]) { check_fail = 1; break; } + if (check_fail) { puts("Err:Req>Need"); goto R; } // Ask for next request + + // Check 2: Request <= Available + check_fail = 0; + for(j=0; j av[j]) { check_fail = 1; break; } + if (check_fail) { puts("Wait:Req>Avail"); goto R; } // Ask for next request + + // Tentatively allocate resources + for(j=0; j +#include +#include +#include +#include + +// Define task structure +typedef struct { + int id; + int period; + int deadline; + int execution_time; + void (*task_function)(void); + int remaining_time; +} task_t; + +// Define global variables +task_t tasks[3]; // Example with 3 tasks +int num_tasks = 3; +pthread_t task_threads[3]; +sem_t scheduler_sem; +int current_time = 0; + +// Task functions (example) +void task1_function() { + printf("Task 1 executing at time %d\n", current_time); + usleep(tasks[0].execution_time * 1000); // Simulate execution time +} + +void task2_function() { + printf("Task 2 executing at time %d\n", current_time); + usleep(tasks[1].execution_time * 1000); // Simulate execution time +} + +void task3_function() { + printf("Task 3 executing at time %d\n", current_time); + usleep(tasks[2].execution_time * 1000); // Simulate execution time +} + +// EDF Scheduler +int edf_scheduler() { + int earliest_deadline = 100000; // Initialize with a large value + int earliest_task_index = -1; + + for (int i = 0; i < num_tasks; i++) { + if (tasks[i].remaining_time > 0 && tasks[i].deadline < earliest_deadline) { + earliest_deadline = tasks[i].deadline; + earliest_task_index = i; + } + } + + return earliest_task_index; +} + +// Rate Monotonic Scheduler (RMS) - Simplified for Demonstration +int rms_scheduler() { + int shortest_period = 100000; // Initialize with a large value + int shortest_period_task_index = -1; + + for (int i = 0; i < num_tasks; i++) { + if (tasks[i].remaining_time > 0 && tasks[i].period < shortest_period) { + shortest_period = tasks[i].period; + shortest_period_task_index = i; + } + } + + return shortest_period_task_index; +} + + +// Task thread function +void *task_thread(void *arg) { + task_t *task = (task_t *)arg; + + while (1) { + sem_wait(&scheduler_sem); // Wait for scheduler to release + + if (task->remaining_time > 0) { + task->task_function(); + task->remaining_time -= task->execution_time; + + if (task->remaining_time <= 0) { + printf("Task %d completed at time %d\n", task->id, current_time); + } + } + + } + pthread_exit(NULL); +} + +int main() { + // Initialize tasks (EDF Example) + tasks[0].id = 1; + tasks[0].period = 50; + tasks[0].deadline = 50; + tasks[0].execution_time = 10; + tasks[0].task_function = task1_function; + tasks[0].remaining_time = tasks[0].execution_time; + + tasks[1].id = 2; + tasks[1].period = 100; + tasks[1].deadline = 100; + tasks[1].execution_time = 15; + tasks[1].task_function = task2_function; + tasks[1].remaining_time = tasks[1].execution_time; + + tasks[2].id = 3; + tasks[2].period = 200; + tasks[2].deadline = 200; + tasks[2].execution_time = 20; + tasks[2].task_function = task3_function; + tasks[2].remaining_time = tasks[2].execution_time; + + // Initialize semaphore + sem_init(&scheduler_sem, 0, 0); + + // Create task threads + for (int i = 0; i < num_tasks; i++) { + pthread_create(&task_threads[i], NULL, task_thread, &tasks[i]); + } + + // RTOS Scheduler Loop + for (current_time = 0; current_time < 500; current_time++) { + // Choose scheduling algorithm (EDF or RMS) + int next_task_index = edf_scheduler(); // Use EDF + //int next_task_index = rms_scheduler(); // Or Use RMS + + if (next_task_index != -1) { + sem_post(&scheduler_sem); // Release the semaphore to the selected task + } + + usleep(1000); // Simulate 1ms time slice + + // Update deadlines for EDF scheduler + for (int i = 0; i < num_tasks; i++) { + if (current_time % tasks[i].period == 0) { + tasks[i].deadline = current_time + tasks[i].period; + tasks[i].remaining_time = tasks[i].execution_time; + printf("Task %d released at time %d, deadline = %d\n", tasks[i].id, current_time, tasks[i].deadline); + + } + } + } + + // Clean up + for (int i = 0; i < num_tasks; i++) { + pthread_cancel(task_threads[i]); + } + sem_destroy(&scheduler_sem); + + return 0; +}