#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; }