Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include <pthread.h>
- #include <sys/time.h>
- #define MAX_ps 1000
- #define BUFFER_SIZE 1000000
- struct process {
- int id;
- int burst_time;
- int arrival_time;
- int process_priority;
- };
- struct shared {
- int quantum;
- int process_count;
- struct process ps[MAX_ps];
- FILE *output_file;
- };
- pthread_mutex_t write_mutex = PTHREAD_MUTEX_INITIALIZER;
- void sort_by_arrival_time(struct process ps_copy[MAX_ps], int process_count) {
- for (int i = 0; i < process_count - 1; i++) {
- for (int j = 0; j < process_count - i - 1; j++) {
- if (ps_copy[j].arrival_time > ps_copy[j + 1].arrival_time) {
- struct process temp = ps_copy[j];
- ps_copy[j] = ps_copy[j + 1];
- ps_copy[j + 1] = temp;
- }
- }
- }
- }
- void output(FILE *fp, char *buffer) {
- pthread_mutex_lock(&write_mutex);
- fwrite(buffer, sizeof(char), strlen(buffer), fp);
- printf("%s", buffer);
- pthread_mutex_unlock(&write_mutex);
- }
- void read_input(char *input_file_path, struct shared *shared) {
- FILE *input = fopen(input_file_path, "r");
- fscanf(input, "Quantum time: %d", &shared->quantum);
- // Skip 2 lines
- char buffer[128];
- fgets(buffer, sizeof(buffer), input);
- fgets(buffer, sizeof(buffer), input);
- int i = 0;
- while (fscanf(input, "%d %d %d", &shared->ps[i].burst_time, &shared->ps[i].arrival_time,
- &shared->ps[i].process_priority) == 3) {
- shared->ps[i].id = i + 1;
- i++;
- }
- shared->process_count = i;
- }
- void copy_and_sort_processes(struct process ps_copy[MAX_ps], struct shared *shared) {
- for (int i = 0; i < shared->process_count; i++) {
- ps_copy[i] = shared->ps[i];
- }
- sort_by_arrival_time(ps_copy, shared->process_count);
- }
- void *fcfs(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- sprintf(output_buffer, "First Come First Serve:\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
- for (int i = 0; i < shared->process_count; i++) {
- struct process current = ps_copy[i];
- if (current.arrival_time > current_time) {
- current_time = current.arrival_time;
- }
- current_time += current.burst_time;
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
- turnaround);
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- void *round_robin(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- int completed = 0;
- int remaining_burst[MAX_ps];
- for (int i = 0; i < shared->process_count; i++) {
- remaining_burst[i] = ps_copy[i].burst_time;
- }
- sprintf(output_buffer, "Round Robin:\nProcess ID\tBurst Time\tTurnaround Time\tWaiting Time\n");
- while (completed < shared->process_count) {
- for (int i = 0; i < shared->process_count; i++) {
- // already completed before
- if (remaining_burst[i] == 0) continue;
- struct process current = ps_copy[i];
- if (current.arrival_time > current_time) {
- continue;
- };
- if (remaining_burst[i] <= shared->quantum) {
- current_time += remaining_burst[i];
- remaining_burst[i] = 0;
- printf("Completed something!");
- completed++;
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id,
- current.burst_time,
- turnaround, wait);
- } else {
- current_time += shared->quantum;
- remaining_burst[i] -= shared->quantum;
- }
- }
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- void *sjf_non_preemptive(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- int finished_count = 0;
- int finished[MAX_ps + 1];
- memset(finished, 0, MAX_ps + 1);
- sprintf(output_buffer,
- "Shortest Job First (non-Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
- while (finished_count < shared->process_count) {
- // Find shortest job
- int shortest_job_idx = -1;
- int shortest_job = INT_MAX;
- for (int i = 0; i < shared->process_count; i++) {
- if (finished[i]) continue;
- if (ps_copy[i].arrival_time > current_time) continue;
- if (ps_copy[i].burst_time < shortest_job) {
- shortest_job_idx = i;
- shortest_job = ps_copy[i].burst_time;
- }
- }
- struct process current = ps_copy[shortest_job_idx];
- finished[shortest_job_idx] = 1;
- finished_count++;
- current_time += current.burst_time;
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
- turnaround);
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- void *sjf_preemptive(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- int time_spent[MAX_ps + 1];
- memset(time_spent, 0, MAX_ps + 1);
- sprintf(output_buffer, "Shortest Job First (Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
- while (1) {
- // Find shortest job that is not yet finished.
- int shortest_job_idx = -1;
- int shortest_job = INT_MAX;
- for (int i = 0; i < shared->process_count; i++) {
- if (time_spent[i] == ps_copy[i].burst_time) continue;
- if (ps_copy[i].arrival_time > current_time) continue;
- if (ps_copy[i].burst_time < shortest_job) {
- shortest_job_idx = i;
- shortest_job = ps_copy[i].burst_time;
- }
- }
- if (shortest_job_idx == -1) {
- // All jobs are finished
- break;
- }
- struct process current = ps_copy[shortest_job_idx];
- current_time += 1;
- time_spent[shortest_job_idx]++;
- if (time_spent[shortest_job_idx] != ps_copy[shortest_job_idx].burst_time) {
- continue;
- }
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
- turnaround);
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- void *priority_non_preemptive(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- int finished_count = 0;
- int finished[MAX_ps + 1];
- memset(finished, 0, MAX_ps + 1);
- sprintf(output_buffer, "Priority (non-Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
- while (finished_count < shared->process_count) {
- // Find job with low priority
- int priority_job_idx = -1;
- int lowest_priority = INT_MAX;
- for (int i = 0; i < shared->process_count; i++) {
- if (finished[i]) continue;
- if (ps_copy[i].arrival_time > current_time) continue;
- if (ps_copy[i].process_priority < lowest_priority) {
- priority_job_idx = i;
- lowest_priority = ps_copy[i].process_priority;
- }
- }
- struct process current = ps_copy[priority_job_idx];
- finished[priority_job_idx] = 1;
- finished_count++;
- current_time += current.burst_time;
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
- turnaround);
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- void *priority_preemptive(void *vargp) {
- struct shared *shared = (struct shared *) vargp;
- struct process ps_copy[MAX_ps];
- copy_and_sort_processes(ps_copy, shared);
- char output_buffer[BUFFER_SIZE];
- int current_time = 0;
- float total_waiting = 0;
- float total_turnaround = 0;
- int time_spent[MAX_ps + 1];
- memset(time_spent, 0, MAX_ps + 1);
- sprintf(output_buffer, "Priority (Preemptive):\nProcess ID\tBurst Time\tWaiting Time\tTurnaround Time\n");
- while (1) {
- // Find job with high priority
- int priority_job_idx = -1;
- int lowest_priority = INT_MAX;
- for (int i = 0; i < shared->process_count; i++) {
- if (time_spent[i] == ps_copy[i].burst_time) continue;
- if (ps_copy[i].arrival_time > current_time) continue;
- if (ps_copy[i].process_priority < lowest_priority) {
- priority_job_idx = i;
- lowest_priority = ps_copy[i].process_priority;
- }
- }
- if (priority_job_idx == -1) {
- // All jobs are finished
- break;
- }
- struct process current = ps_copy[priority_job_idx];
- current_time += 1;
- time_spent[priority_job_idx]++;
- if (time_spent[priority_job_idx] != ps_copy[priority_job_idx].burst_time) {
- continue;
- }
- int wait = current_time - current.arrival_time - current.burst_time;
- int turnaround = current_time - current.arrival_time;
- total_waiting += wait;
- total_turnaround += turnaround;
- sprintf(output_buffer, "%sProcess [%d]\t%d\t\t%d\t\t%d\n", output_buffer, current.id, current.burst_time, wait,
- turnaround);
- }
- sprintf(output_buffer, "%sAverage waiting time: %f\n", output_buffer, total_waiting / shared->process_count);
- sprintf(output_buffer, "%sAverage turnaround time: %f\n\n\n", output_buffer,
- total_turnaround / shared->process_count);
- output(shared->output_file, output_buffer);
- }
- int main(int argc, char *argv[]) {
- char *input_file_name = getenv("INPUT_FILE_NAME");
- if (input_file_name == NULL) {
- printf("Input file not specified, using input.txt");
- input_file_name = "input.txt";
- }
- struct shared *shared = malloc(sizeof(struct shared));
- read_input(input_file_name, shared);
- char buffer[BUFFER_SIZE];
- printf("Input:\n");
- printf("Quantum: %d\n", shared->quantum);
- printf("Process count: %d\n", shared->process_count);
- printf("Process ID\tBurst Time\tArrival Time\tPriority\n");
- for (int i = 0; i < shared->process_count; i++) {
- printf("Process [%d]\t%d\t\t%d\t\t%d\n", shared->ps[i].id,
- shared->ps[i].burst_time,
- shared->ps[i].arrival_time, shared->ps[i].process_priority);
- }
- printf("\n\n");
- struct timeval t_start, t_end;
- // Run sequentially
- FILE *output_file = fopen("output-sequential.txt", "w");
- shared->output_file = output_file;
- gettimeofday(&t_start, NULL);
- fcfs(shared);
- round_robin(shared);
- sjf_non_preemptive(shared);
- sjf_preemptive(shared);
- priority_non_preemptive(shared);
- priority_preemptive(shared);
- gettimeofday(&t_end, NULL);
- double elapsed = (t_end.tv_sec - t_start.tv_sec)
- + (t_end.tv_usec - t_start.tv_usec) / 1e6;
- sprintf(buffer, "Total time of execution: %.6f\n", elapsed);
- output(output_file, buffer);
- fclose(output_file);
- printf("------------------------------------------\n\n");
- // Run again concurrently
- output_file = fopen("output-concurrent.txt", "w");
- shared->output_file = output_file;
- gettimeofday(&t_start, NULL);
- pthread_t tid[6];
- pthread_create(&tid[0], NULL, fcfs, shared);
- pthread_create(&tid[1], NULL, round_robin, shared);
- pthread_create(&tid[2], NULL, sjf_non_preemptive, shared);
- pthread_create(&tid[3], NULL, sjf_preemptive, shared);
- pthread_create(&tid[4], NULL, priority_non_preemptive, shared);
- pthread_create(&tid[5], NULL, priority_preemptive, shared);
- for (int i = 0; i < 6; i++) {
- pthread_join(tid[i],NULL);
- }
- gettimeofday(&t_end, NULL);
- elapsed = (t_end.tv_sec - t_start.tv_sec)
- + (t_end.tv_usec - t_start.tv_usec) / 1e6;
- sprintf(buffer, "Total time of execution: %.6f\n", elapsed);
- output(output_file, buffer);
- fclose(output_file);
- free(shared);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement