From 5bf4ac12da85508e77ed0dcdac6f6b60c7693504 Mon Sep 17 00:00:00 2001 From: Aadit Agrawal Date: Fri, 7 Feb 2025 11:30:13 +0530 Subject: [PATCH] Add OS/C/Week6/menudriven.c --- OS/C/Week6/menudriven.c | 393 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 OS/C/Week6/menudriven.c diff --git a/OS/C/Week6/menudriven.c b/OS/C/Week6/menudriven.c new file mode 100644 index 0000000..fcff5f2 --- /dev/null +++ b/OS/C/Week6/menudriven.c @@ -0,0 +1,393 @@ +#include +#include +#include +#include + +# define MAX 4 + + typedef struct { + char pid[5]; // Process ID (string) + int at; // Arrival Time + int bt; // Burst Time + int priority; // Priority (lower value = higher priority) + int ct; // Completion Time + int tat; // Turnaround Time + int wt; // Waiting Time + int rt; // Response Time + int remaining_bt; // Remaining Burst Time (for preemptive sjf) + int is_completed; // completion flag + } Process; + + void swap(Process *a, Process *b) { + Process temp = *a; + *a = *b; + *b = temp; + } + + + // Function to calculate Completion Time, Turnaround Time, and Waiting Time + void calculate_times(Process processes[], int n) { + for (int i = 0; i < n; i++) { + processes[i].tat = processes[i].ct - processes[i].at; + processes[i].wt = processes[i].tat - processes[i].bt; + } + } + + + // Function to calculate average times + void calculate_averages(Process processes[], int n, float *avg_ct, + float *avg_tat, float *avg_wt, float *avg_rt) { + *avg_ct = 0; + *avg_tat = 0; + *avg_wt = 0; + *avg_rt = 0; + + + for (int i = 0; i < n; i++) { + *avg_ct += processes[i].ct; + *avg_tat += processes[i].tat; + *avg_wt += processes[i].wt; + *avg_rt += processes[i].rt; + } + + + *avg_ct /= n; + *avg_tat /= n; + *avg_wt /= n; + *avg_rt /= n; + } + + // Function to display the Gantt chart + void display_gantt_chart(Process processes[], int n, int timeline[]) { + printf("\nGantt Chart:\n"); + printf("-----------------------------------------------------------\n"); + for (int i = 0; i <= timeline[n - 1]; i++) { + printf("%-3d", i); + } + + printf("\n-----------------------------------------------------------\n"); + + for (int i = 0; i < n; i++) { + printf("%-3s", processes[i].pid); + } + + printf("\n-----------------------------------------------------------\n"); + } + + + // Function to display the process table + void display_table(Process processes[], int n) { + printf("--------------------------------------------------------------------" + "------\n"); + printf("| PID | AT | BT | CT | TAT | WT | RT |\n"); + printf("--------------------------------------------------------------------" + "------\n"); + for (int i = 0; i < n; i++) { + printf("| %-5s | %-3d | %-3d | %-3d | %-3d | %-3d | %-3d |\n", + processes[i].pid, processes[i].at, processes[i].bt, + processes[i].ct, processes[i].tat, processes[i].wt, + processes[i].rt); + } + printf("--------------------------------------------------------------------" + "------\n"); + } + + // Preemptive SJF + void preemptive_sjf(Process processes[], int n){ + + // process sort by AT + for (int i = 0; i < n -1; i++){ + for(int j = 0; j < n - i - 1; j++){ + if(processes[j].at > processes[j+1].at){ + swap(&processes[j], &processes[j + 1]); + } + } + } + + //remaining BT + completion flag + for (int i = 0; i < n; i++){ + processes[i].remaining_bt = processes[i].bt; + processes[i].rt = -1; + processes[i].is_completed = 0; + } + + // init for values of relevant variables, shortest=-1 to indicate no process is selected + int current_time = 0; + int completed = 0; + int shortest = -1; + + int *timeline = (int *)malloc((n*2)*sizeof(int)); + if (timeline == NULL) { + perror ("MemAlloc Error"); + return; + } + + int timeline_index = 0; + + // setting to large values to prevent issues + while (completed != n) + { + shortest = -1; + int min_bt = 9999; + + for (int j = 0; j < n; j++) { + if (processes[j].at <= current_time && processes[j].remaining_bt > 0 && processes[j].remaining_bt < min_bt){ + min_bt = processes[j].remaining_bt; + shortest = j; + } + } + + if (shortest == -1){ + current_time++; + continue; + } + + if(processes[shortest].rt == -1) { + processes[shortest].rt = current_time - processes[shortest].at; + } + + processes[shortest].remaining_bt--; + current_time++; + + + if (processes[shortest].remaining_bt == 0) { + completed++; + processes[shortest].ct = current_time; + processes[shortest].is_completed = 1; + } + + timeline[timeline_index++] = current_time; + } + + calculate_times(processes, n); + + float avg_ct, avg_tat, avg_wt, avg_rt; + calculate_averages(processes, n, &avg_ct, &avg_tat, &avg_wt, &avg_rt); + + + printf("\nPreemptive SJF Scheduling:\n"); + display_table(processes, n); + + + printf("\nAverage Completion Time: %.2f\n", avg_ct); + printf("Average Turnaround Time: %.2f\n", avg_tat); + printf("Average Waiting Time: %.2f\n", avg_wt); + printf("Average Response Time: %.2f\n", avg_rt); + + + display_gantt_chart(processes, n, timeline); + free(timeline); +} + + void round_robin(Process processes[], int n, int quantum) { + + for (int i = 0; i < n; i++) { + processes[i].remaining_bt = processes[i].bt; + processes[i].rt = -1; + processes[i].is_completed = 0; + } + + + int current_time = 0; + int completed = 0; + int i = 0; + int *timeline = (int *)malloc((n * 2) * sizeof(int)); // memory for timeline + + if (timeline == NULL) { + perror("Failed to allocate memory for timeline"); + return; + } + + int timeline_index = 0; + + + while (completed != n) { + if (processes[i].remaining_bt > 0 && processes[i].at <= current_time) { + if (processes[i].rt == -1) { + processes[i].rt = current_time - processes[i].at; + } + + int execute_time = (processes[i].remaining_bt > quantum) ? quantum : processes[i].remaining_bt; processes[i].remaining_bt -= execute_time; current_time += execute_time; + + if (processes[i].remaining_bt == 0) { + completed++; + processes[i].ct = current_time; + processes[i].is_completed = 1; + } + + timeline[timeline_index++] = current_time; + + } else if (processes[i].at > current_time) { + current_time++; // if process hasn't arrived, time is incremented (to prevent a stall) + } + + + i = (i + 1) % n; + if (current_time > 1000) break; + } + + + calculate_times(processes, n); + + + float avg_ct, avg_tat, avg_wt, avg_rt; + calculate_averages(processes, n, &avg_ct, &avg_tat, &avg_wt, &avg_rt); + + + printf("\nRound Robin Scheduling (Quantum = %d):\n", quantum); + display_table(processes, n); + + + printf("\nAverage Completion Time: %.2f\n", avg_ct); + printf("Average Turnaround Time: %.2f\n", avg_tat); + printf("Average Waiting Time: %.2f\n", avg_wt); + printf("Average Response Time: %.2f\n", avg_rt); + + + display_gantt_chart(processes, n, timeline); + free(timeline); // Free memory + } + + + void non_preemptive_priority(Process processes[], int n) { + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (processes[j].at > processes[j + 1].at) { + swap(&processes[j], &processes[j + 1]); + } + } + } + + int current_time = 0; + int completed = 0; + int *timeline = (int *)malloc((n * 2) * sizeof(int)); + + if (timeline == NULL) { + perror("Failed to allocate memory for timeline"); + return; + } + + int timeline_index = 0; + + while (completed != n) { + int highest_priority = -1; + int min_priority = 9999; // Large value + + + for (int j = 0; j < n; j++) { + if (processes[j].at <= current_time && processes[j].bt > 0 && processes[j].priority < min_priority) { + min_priority = processes[j].priority; + highest_priority = j; + } + } + + if (highest_priority == -1) { + current_time++; + continue; + } + + if (processes[highest_priority].rt == -1) { + processes[highest_priority].rt = + current_time - processes[highest_priority].at; + } + + current_time += processes[highest_priority].bt; + + processes[highest_priority].ct = current_time; + processes[highest_priority].bt = 0; // Mark completed + + completed++; + timeline[timeline_index++] = current_time; + } + + calculate_times(processes, n); + + float avg_ct, avg_tat, avg_wt, avg_rt; + calculate_averages(processes, n, &avg_ct, &avg_tat, &avg_wt, &avg_rt); + + printf("\nNon-Preemptive Priority Scheduling:\n"); + display_table(processes, n); + + printf("\nAverage Completion Time: %.2f\n", avg_ct); + printf("Average Turnaround Time: %.2f\n", avg_tat); + printf("Average Waiting Time: %.2f\n", avg_wt); + printf("Average Response Time: %.2f\n", avg_rt); + + display_gantt_chart(processes, n, timeline); + free(timeline); // Free memory + } + + + int main() { + int n, choice, quantum; + + printf("Enter the number of processes: "); + scanf("%d", &n); + + Process processes[n]; + + // Input process details + for (int i = 0; i < n; i++) { + printf("\nEnter details for process %d:\n", i + 1); + + printf("PID: "); + scanf("%s", processes[i].pid); + + printf("Arrival Time: "); + scanf("%d", &processes[i].at); + + printf("Burst Time: "); + scanf("%d", &processes[i].bt); + + printf("Priority (lower value = higher priority): "); + scanf("%d", &processes[i].priority); + + processes[i].rt = 0; // Initialize response time + processes[i].is_completed = 0; // Initialize completion flag + } + + // Display initial table + printf("\nInitial Process Table:\n"); + printf("-----------------------\n"); + printf("| PID | AT | BT |\n"); + printf("-----------------------\n"); + + for (int i = 0; i < n; i++) { + printf("| %-5s | %-3d | %-3d |\n", processes[i].pid, processes[i].at, processes[i].bt); + } + + printf("-----------------------\n"); + + // Algorithm Selection Menu with Loop and Exit + while (1) { + printf("\nChoose a scheduling algorithm:\n"); + printf("1. Preemptive SJF\n"); + printf("2. Round Robin\n"); + printf("3. Non-Preemptive Priority\n"); + printf("4. Exit\n"); + printf("Enter your choice: "); + + scanf("%d", &choice); + + switch (choice) { + case 1: + preemptive_sjf(processes, n); + break; + case 2: + printf("Enter the time quantum: "); + scanf("%d", &quantum); + round_robin(processes, n, quantum); + break; + case 3: + non_preemptive_priority(processes, n); + break; + case 4: + printf("Exiting program.\n"); + exit(0); + default: + printf("Invalid choice. Please try again.\n"); + } + } + + return 0; + }