Advertisement
BlackArrow502

Untitled

May 2nd, 2025
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.46 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include <pthread.h>
  6. #include <sys/time.h>
  7.  
  8.  
  9. #define MAX_ps 1000
  10. #define BUFFER_SIZE 1000000
  11.  
  12. struct process {
  13.     int id;
  14.     int burst_time;
  15.     int arrival_time;
  16.     int process_priority;
  17. };
  18.  
  19. struct shared {
  20.     int quantum;
  21.     int process_count;
  22.     struct process ps[MAX_ps];
  23.     FILE *output_file;
  24. };
  25.  
  26. pthread_mutex_t write_mutex = PTHREAD_MUTEX_INITIALIZER;
  27.  
  28. void sort_by_arrival_time(struct process ps_copy[MAX_ps], int process_count) {
  29.     for (int i = 0; i < process_count - 1; i++) {
  30.         for (int j = 0; j < process_count - i - 1; j++) {
  31.             if (ps_copy[j].arrival_time > ps_copy[j + 1].arrival_time) {
  32.                 struct process temp = ps_copy[j];
  33.                 ps_copy[j] = ps_copy[j + 1];
  34.                 ps_copy[j + 1] = temp;
  35.             }
  36.         }
  37.     }
  38. }
  39.  
  40. void output(FILE *fp, char *buffer) {
  41.     pthread_mutex_lock(&write_mutex);
  42.     fwrite(buffer, sizeof(char), strlen(buffer), fp);
  43.     printf("%s", buffer);
  44.     pthread_mutex_unlock(&write_mutex);
  45. }
  46.  
  47. void read_input(char *input_file_path, struct shared *shared) {
  48.     FILE *input = fopen(input_file_path, "r");
  49.  
  50.     fscanf(input, "Quantum time: %d", &shared->quantum);
  51.  
  52.     // Skip 2 lines
  53.     char buffer[128];
  54.     fgets(buffer, sizeof(buffer), input);
  55.     fgets(buffer, sizeof(buffer), input);
  56.  
  57.     int i = 0;
  58.     while (fscanf(input, "%d %d %d", &shared->ps[i].burst_time, &shared->ps[i].arrival_time,
  59.                   &shared->ps[i].process_priority) == 3) {
  60.         shared->ps[i].id = i + 1;
  61.         i++;
  62.     }
  63.     shared->process_count = i;
  64. }
  65.  
  66. void copy_and_sort_processes(struct process ps_copy[MAX_ps], struct shared *shared) {
  67.     for (int i = 0; i < shared->process_count; i++) {
  68.         ps_copy[i] = shared->ps[i];
  69.     }
  70.     sort_by_arrival_time(ps_copy, shared->process_count);
  71. }
  72.  
  73. void *fcfs(void *vargp) {
  74.     struct shared *shared = (struct shared *) vargp;
  75.     struct process ps_copy[MAX_ps];
  76.     copy_and_sort_processes(ps_copy, shared);
  77.     char output_buffer[BUFFER_SIZE];
  78.     int current_time = 0;
  79.     float total_waiting = 0;
  80.     float total_turnaround = 0;
  81.  
  82.     sprintf(output_buffer, "First Come First Serve:\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
  83.     for (int i = 0; i < shared->process_count; i++) {
  84.         struct process current = ps_copy[i];
  85.  
  86.         if (current.arrival_time > current_time) {
  87.             current_time = current.arrival_time;
  88.         }
  89.  
  90.         current_time += current.burst_time;
  91.  
  92.         int wait = current_time - current.arrival_time - current.burst_time;
  93.         int turnaround = current_time - current.arrival_time;
  94.         total_waiting += wait;
  95.         total_turnaround += turnaround;
  96.  
  97.         sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
  98.                 turnaround);
  99.     }
  100.  
  101.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  102.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  103.             total_turnaround / shared->process_count);
  104.     output(shared->output_file, output_buffer);
  105. }
  106.  
  107. void *round_robin(void *vargp) {
  108.     struct shared *shared = (struct shared *) vargp;
  109.     struct process ps_copy[MAX_ps];
  110.     copy_and_sort_processes(ps_copy, shared);
  111.     char output_buffer[BUFFER_SIZE];
  112.     int current_time = 0;
  113.     float total_waiting = 0;
  114.     float total_turnaround = 0;
  115.  
  116.     int completed = 0;
  117.     int remaining_burst[MAX_ps];
  118.     for (int i = 0; i < shared->process_count; i++) {
  119.         remaining_burst[i] = ps_copy[i].burst_time;
  120.     }
  121.  
  122.     sprintf(output_buffer, "Round Robin:\nProcess ID\tBurst Time\tTurnaround Time\tWaiting Time\n");
  123.     while (completed < shared->process_count) {
  124.         for (int i = 0; i < shared->process_count; i++) {
  125.             // already completed before
  126.             if (remaining_burst[i] == 0) continue;
  127.  
  128.             struct process current = ps_copy[i];
  129.             if (current.arrival_time > current_time) {
  130.                 continue;
  131.             };
  132.  
  133.             if (remaining_burst[i] <= shared->quantum) {
  134.                 current_time += remaining_burst[i];
  135.                 remaining_burst[i] = 0;
  136.                 printf("Completed something!");
  137.                 completed++;
  138.  
  139.                 int wait = current_time - current.arrival_time - current.burst_time;
  140.                 int turnaround = current_time - current.arrival_time;
  141.                 total_waiting += wait;
  142.                 total_turnaround += turnaround;
  143.  
  144.                 sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id,
  145.                         current.burst_time,
  146.                         turnaround, wait);
  147.             } else {
  148.                 current_time += shared->quantum;
  149.                 remaining_burst[i] -= shared->quantum;
  150.             }
  151.         }
  152.     }
  153.  
  154.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  155.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  156.             total_turnaround / shared->process_count);
  157.     output(shared->output_file, output_buffer);
  158. }
  159.  
  160. void *sjf_non_preemptive(void *vargp) {
  161.     struct shared *shared = (struct shared *) vargp;
  162.     struct process ps_copy[MAX_ps];
  163.     copy_and_sort_processes(ps_copy, shared);
  164.     char output_buffer[BUFFER_SIZE];
  165.     int current_time = 0;
  166.     float total_waiting = 0;
  167.     float total_turnaround = 0;
  168.  
  169.     int finished_count = 0;
  170.     int finished[MAX_ps + 1];
  171.     memset(finished, 0, MAX_ps + 1);
  172.  
  173.     sprintf(output_buffer,
  174.             "Shortest Job First (non-Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
  175.     while (finished_count < shared->process_count) {
  176.         // Find shortest job
  177.         int shortest_job_idx = -1;
  178.         int shortest_job = INT_MAX;
  179.         for (int i = 0; i < shared->process_count; i++) {
  180.             if (finished[i]) continue;
  181.             if (ps_copy[i].arrival_time > current_time) continue;
  182.             if (ps_copy[i].burst_time < shortest_job) {
  183.                 shortest_job_idx = i;
  184.                 shortest_job = ps_copy[i].burst_time;
  185.             }
  186.         }
  187.  
  188.         struct process current = ps_copy[shortest_job_idx];
  189.         finished[shortest_job_idx] = 1;
  190.         finished_count++;
  191.         current_time += current.burst_time;
  192.  
  193.         int wait = current_time - current.arrival_time - current.burst_time;
  194.         int turnaround = current_time - current.arrival_time;
  195.         total_waiting += wait;
  196.         total_turnaround += turnaround;
  197.  
  198.         sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
  199.                 turnaround);
  200.     }
  201.  
  202.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  203.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  204.             total_turnaround / shared->process_count);
  205.     output(shared->output_file, output_buffer);
  206. }
  207.  
  208. void *sjf_preemptive(void *vargp) {
  209.     struct shared *shared = (struct shared *) vargp;
  210.     struct process ps_copy[MAX_ps];
  211.     copy_and_sort_processes(ps_copy, shared);
  212.     char output_buffer[BUFFER_SIZE];
  213.     int current_time = 0;
  214.     float total_waiting = 0;
  215.     float total_turnaround = 0;
  216.  
  217.     int time_spent[MAX_ps + 1];
  218.     memset(time_spent, 0, MAX_ps + 1);
  219.  
  220.     sprintf(output_buffer, "Shortest Job First (Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
  221.     while (1) {
  222.         // Find shortest job that is not yet finished.
  223.         int shortest_job_idx = -1;
  224.         int shortest_job = INT_MAX;
  225.         for (int i = 0; i < shared->process_count; i++) {
  226.             if (time_spent[i] == ps_copy[i].burst_time) continue;
  227.             if (ps_copy[i].arrival_time > current_time) continue;
  228.             if (ps_copy[i].burst_time < shortest_job) {
  229.                 shortest_job_idx = i;
  230.                 shortest_job = ps_copy[i].burst_time;
  231.             }
  232.         }
  233.         if (shortest_job_idx == -1) {
  234.             // All jobs are finished
  235.             break;
  236.         }
  237.  
  238.         struct process current = ps_copy[shortest_job_idx];
  239.         current_time += 1;
  240.         time_spent[shortest_job_idx]++;
  241.  
  242.         if (time_spent[shortest_job_idx] != ps_copy[shortest_job_idx].burst_time) {
  243.             continue;
  244.         }
  245.  
  246.         int wait = current_time - current.arrival_time - current.burst_time;
  247.         int turnaround = current_time - current.arrival_time;
  248.         total_waiting += wait;
  249.         total_turnaround += turnaround;
  250.  
  251.         sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
  252.                 turnaround);
  253.     }
  254.  
  255.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  256.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  257.             total_turnaround / shared->process_count);
  258.     output(shared->output_file, output_buffer);
  259. }
  260.  
  261. void *priority_non_preemptive(void *vargp) {
  262.     struct shared *shared = (struct shared *) vargp;
  263.     struct process ps_copy[MAX_ps];
  264.     copy_and_sort_processes(ps_copy, shared);
  265.     char output_buffer[BUFFER_SIZE];
  266.     int current_time = 0;
  267.     float total_waiting = 0;
  268.     float total_turnaround = 0;
  269.  
  270.     int finished_count = 0;
  271.     int finished[MAX_ps + 1];
  272.     memset(finished, 0, MAX_ps + 1);
  273.  
  274.     sprintf(output_buffer, "Priority (non-Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
  275.     while (finished_count < shared->process_count) {
  276.         // Find job with low priority
  277.         int priority_job_idx = -1;
  278.         int lowest_priority = INT_MAX;
  279.         for (int i = 0; i < shared->process_count; i++) {
  280.             if (finished[i]) continue;
  281.             if (ps_copy[i].arrival_time > current_time) continue;
  282.             if (ps_copy[i].process_priority < lowest_priority) {
  283.                 priority_job_idx = i;
  284.                 lowest_priority = ps_copy[i].process_priority;
  285.             }
  286.         }
  287.  
  288.         struct process current = ps_copy[priority_job_idx];
  289.         finished[priority_job_idx] = 1;
  290.         finished_count++;
  291.         current_time += current.burst_time;
  292.  
  293.         int wait = current_time - current.arrival_time - current.burst_time;
  294.         int turnaround = current_time - current.arrival_time;
  295.         total_waiting += wait;
  296.         total_turnaround += turnaround;
  297.  
  298.         sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
  299.                 turnaround);
  300.     }
  301.  
  302.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  303.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  304.             total_turnaround / shared->process_count);
  305.     output(shared->output_file, output_buffer);
  306. }
  307.  
  308. void *priority_preemptive(void *vargp) {
  309.     struct shared *shared = (struct shared *) vargp;
  310.     struct process ps_copy[MAX_ps];
  311.     copy_and_sort_processes(ps_copy, shared);
  312.     char output_buffer[BUFFER_SIZE];
  313.     int current_time = 0;
  314.     float total_waiting = 0;
  315.     float total_turnaround = 0;
  316.  
  317.     int time_spent[MAX_ps + 1];
  318.     memset(time_spent, 0, MAX_ps + 1);
  319.  
  320.     sprintf(output_buffer, "Priority (Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
  321.     while (1) {
  322.         // Find job with high priority
  323.         int priority_job_idx = -1;
  324.         int lowest_priority = INT_MAX;
  325.         for (int i = 0; i < shared->process_count; i++) {
  326.             if (time_spent[i] == ps_copy[i].burst_time) continue;
  327.             if (ps_copy[i].arrival_time > current_time) continue;
  328.             if (ps_copy[i].process_priority < lowest_priority) {
  329.                 priority_job_idx = i;
  330.                 lowest_priority = ps_copy[i].process_priority;
  331.             }
  332.         }
  333.         if (priority_job_idx == -1) {
  334.             // All jobs are finished
  335.             break;
  336.         }
  337.  
  338.  
  339.         struct process current = ps_copy[priority_job_idx];
  340.         current_time += 1;
  341.         time_spent[priority_job_idx]++;
  342.  
  343.         if (time_spent[priority_job_idx] != ps_copy[priority_job_idx].burst_time) {
  344.             continue;
  345.         }
  346.  
  347.         int wait = current_time - current.arrival_time - current.burst_time;
  348.         int turnaround = current_time - current.arrival_time;
  349.         total_waiting += wait;
  350.         total_turnaround += turnaround;
  351.  
  352.         sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
  353.                 turnaround);
  354.     }
  355.  
  356.     sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
  357.     sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
  358.             total_turnaround / shared->process_count);
  359.     output(shared->output_file, output_buffer);
  360. }
  361.  
  362.  
  363. int main(int argc, char *argv[]) {
  364.     char *input_file_name = getenv("INPUT_FILE_NAME");
  365.     if (input_file_name == NULL) {
  366.         printf("Input file not specified, using input.txt");
  367.         input_file_name = "input.txt";
  368.     }
  369.  
  370.     struct shared *shared = malloc(sizeof(struct shared));
  371.     read_input(input_file_name, shared);
  372.     char buffer[BUFFER_SIZE];
  373.  
  374.     printf("Input:\n");
  375.     printf("Quantum: %d\n", shared->quantum);
  376.     printf("Process count: %d\n", shared->process_count);
  377.     printf("Process ID\tBurst Time\tArrival Time\tPriority\n");
  378.     for (int i = 0; i < shared->process_count; i++) {
  379.         printf("Process [%d]\t%d\t\t%d\t\t%d\n", shared->ps[i].id,
  380.                shared->ps[i].burst_time,
  381.                shared->ps[i].arrival_time, shared->ps[i].process_priority);
  382.     }
  383.  
  384.     printf("\n\n");
  385.  
  386.     struct timeval t_start, t_end;
  387.  
  388.  
  389.     // Run sequentially
  390.     FILE *output_file = fopen("output-sequential.txt", "w");
  391.     shared->output_file = output_file;
  392.  
  393.     gettimeofday(&t_start, NULL);
  394.     fcfs(shared);
  395.     round_robin(shared);
  396.     sjf_non_preemptive(shared);
  397.     sjf_preemptive(shared);
  398.     priority_non_preemptive(shared);
  399.     priority_preemptive(shared);
  400.     gettimeofday(&t_end, NULL);
  401.     double elapsed = (t_end.tv_sec  - t_start.tv_sec)
  402.                + (t_end.tv_usec - t_start.tv_usec) / 1e6;
  403.     sprintf(buffer, "Total time of execution: %.6f\n", elapsed);
  404.     output(output_file, buffer);
  405.     fclose(output_file);
  406.  
  407.     printf("------------------------------------------\n\n");
  408.  
  409.     // Run again concurrently
  410.     output_file = fopen("output-concurrent.txt", "w");
  411.     shared->output_file = output_file;
  412.  
  413.     gettimeofday(&t_start, NULL);
  414.     pthread_t tid[6];
  415.     pthread_create(&tid[0], NULL, fcfs, shared);
  416.     pthread_create(&tid[1], NULL, round_robin, shared);
  417.     pthread_create(&tid[2], NULL, sjf_non_preemptive, shared);
  418.     pthread_create(&tid[3], NULL, sjf_preemptive, shared);
  419.     pthread_create(&tid[4], NULL, priority_non_preemptive, shared);
  420.     pthread_create(&tid[5], NULL, priority_preemptive, shared);
  421.     for (int i = 0; i < 6; i++) {
  422.         pthread_join(tid[i],NULL);
  423.     }
  424.     gettimeofday(&t_end, NULL);
  425.     elapsed = (t_end.tv_sec  - t_start.tv_sec)
  426.                + (t_end.tv_usec - t_start.tv_usec) / 1e6;
  427.     sprintf(buffer, "Total time of execution: %.6f\n", elapsed);
  428.     output(output_file, buffer);
  429.     fclose(output_file);
  430.  
  431.  
  432.     free(shared);
  433.     return 0;
  434. }
  435.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement