Add a5 skeleton
This commit is contained in:
parent
efc8207b13
commit
c1b88cf242
8
Assignment5/.idea/.gitignore
vendored
Normal file
8
Assignment5/.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
2
Assignment5/.idea/Assignment5.iml
Normal file
2
Assignment5/.idea/Assignment5.iml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
8
Assignment5/.idea/cmake.xml
Normal file
8
Assignment5/.idea/cmake.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeSharedSettings">
|
||||||
|
<configurations>
|
||||||
|
<configuration PROFILE_NAME="Debug" ENABLED="true" GENERATION_DIR="build" CONFIG_NAME="Debug" />
|
||||||
|
</configurations>
|
||||||
|
</component>
|
||||||
|
</project>
|
4
Assignment5/.idea/misc.xml
Normal file
4
Assignment5/.idea/misc.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
8
Assignment5/.idea/modules.xml
Normal file
8
Assignment5/.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Assignment5.iml" filepath="$PROJECT_DIR$/.idea/Assignment5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
Assignment5/.idea/vcs.xml
Normal file
6
Assignment5/.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
7
Assignment5/CMakeLists.txt
Normal file
7
Assignment5/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
project(Assignment5 C)
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
include_directories(lib)
|
||||||
|
add_executable(Assignment5 round_robin.c lib/queue.c lib/process.c)
|
BIN
Assignment5/documentation/Assignment 5.pdf
Normal file
BIN
Assignment5/documentation/Assignment 5.pdf
Normal file
Binary file not shown.
7
Assignment5/documentation/a5_sample_input_1.txt
Normal file
7
Assignment5/documentation/a5_sample_input_1.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
1
|
||||||
|
3
|
||||||
|
User Process Arrival Duration
|
||||||
|
Jim A 2 5
|
||||||
|
Mary B 2 2
|
||||||
|
Sue C 5 5
|
||||||
|
Mary D 6 2
|
22
Assignment5/documentation/a5_sample_output_1.txt
Normal file
22
Assignment5/documentation/a5_sample_output_1.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Time CPU0
|
||||||
|
1 -
|
||||||
|
2 A
|
||||||
|
3 A
|
||||||
|
4 A
|
||||||
|
5 B
|
||||||
|
6 B
|
||||||
|
7 A
|
||||||
|
8 A
|
||||||
|
9 C
|
||||||
|
10 C
|
||||||
|
11 C
|
||||||
|
12 D
|
||||||
|
13 D
|
||||||
|
14 C
|
||||||
|
15 C
|
||||||
|
16 -
|
||||||
|
|
||||||
|
Summary
|
||||||
|
Jim 8
|
||||||
|
Mary 13
|
||||||
|
Sue 15
|
36
Assignment5/lib/process.c
Normal file
36
Assignment5/lib/process.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
//Assume that the string passed in is null terminated
|
||||||
|
|
||||||
|
Process *createProcess(char *username, char job, int arrival_time, int duration) {
|
||||||
|
// Allocate memory for the process, and check if it was successful
|
||||||
|
Process *node = calloc(1, sizeof(Process));
|
||||||
|
if (node == NULL) {
|
||||||
|
printf("Error allocating memory for process\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// Free the data first, then allocate memory for the new data
|
||||||
|
node->username = calloc(strlen(username) + 1, sizeof(char));
|
||||||
|
if (node->username == NULL) {
|
||||||
|
printf("Error allocating memory for username data\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// Copy data from the string passed in to the process's data
|
||||||
|
// Makes sure if the string passed in is changed, the process's data is not changed
|
||||||
|
// Also makes sure that if the data is on the stack, it is not freed at some other point
|
||||||
|
strcpy(node->username, username);
|
||||||
|
node->job = job;
|
||||||
|
node->arrival_time = arrival_time;
|
||||||
|
node->duration = duration;
|
||||||
|
node->next_elem = NULL;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyProcess(Process *node) {
|
||||||
|
// Free the data first, then free the process
|
||||||
|
free(node->username);
|
||||||
|
free(node);
|
||||||
|
}
|
18
Assignment5/lib/process.h
Normal file
18
Assignment5/lib/process.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef PROCESS_H
|
||||||
|
#define PROCESS_H
|
||||||
|
|
||||||
|
typedef struct Process {
|
||||||
|
struct Process *prev_elem;
|
||||||
|
struct Process *next_elem;
|
||||||
|
char *username;
|
||||||
|
char job;
|
||||||
|
int arrival_time;
|
||||||
|
int duration;
|
||||||
|
int finish_time;
|
||||||
|
} Process;
|
||||||
|
|
||||||
|
Process *createProcess(char *username, char job, int arrival_time, int duration);
|
||||||
|
|
||||||
|
void destroyProcess(Process *node);
|
||||||
|
|
||||||
|
#endif //PROCESS_H
|
103
Assignment5/lib/queue.c
Normal file
103
Assignment5/lib/queue.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "process.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Queue implementation
|
||||||
|
* 5 4 3 2 1
|
||||||
|
* START END
|
||||||
|
*
|
||||||
|
* If you were to visualize the queue as a line, the end is the first person in line and the start is the last person in line
|
||||||
|
* So when you enqueue, you are adding to the start of the line
|
||||||
|
* And when you dequeue, you are exiting from the end of the line
|
||||||
|
*/
|
||||||
|
|
||||||
|
int contains(Queue *queue, char *username) {
|
||||||
|
Process *current = queue->end;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (strcmp(current->username, username) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
current = current->prev_elem;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Process *search(Queue *queue, char *username) {
|
||||||
|
Process *current = queue->end;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (strcmp(current->username, username) == 0) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
current = current->prev_elem;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void enqueue(Queue *queue, Process *process) {
|
||||||
|
if (queue->end == NULL) { // If the queue is empty, set the start and end to the new process
|
||||||
|
queue->end = process;
|
||||||
|
queue->start = queue->end;
|
||||||
|
} else {
|
||||||
|
process->next_elem = queue->start; // Set the next element of the new process to the start of the queue
|
||||||
|
queue->start->prev_elem = process; // Set the previous element of the start of the queue to the new process
|
||||||
|
queue->start = process; // Set the start of the queue to the new process
|
||||||
|
}
|
||||||
|
queue->size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: Returns a pointer to a process that is not in the queue, it is your responsibility to free it
|
||||||
|
Process *dequeue(Queue *queue) {
|
||||||
|
if (queue->end == NULL) { // If the queue is empty, return NULL
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Process *temp = queue->end; // Store the end of the queue for returning later
|
||||||
|
|
||||||
|
if (queue->size == 1) { // If the queue has one element, set the start and end to NULL
|
||||||
|
queue->start = NULL;
|
||||||
|
queue->end = NULL;
|
||||||
|
queue->size--;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
queue->end = queue->end->prev_elem; // Set the end to the previous element
|
||||||
|
queue->end->next_elem = NULL; // Set the next element of the new end to NULL
|
||||||
|
|
||||||
|
temp->prev_elem = NULL; // The dequeued element should not point to anything
|
||||||
|
queue->size--;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
void printList(Queue *queue) {
|
||||||
|
Process *current = queue->end;
|
||||||
|
while (current != NULL) {
|
||||||
|
printf("%s\t%d\n", current->username, current->finish_time);
|
||||||
|
current = current->prev_elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int stop(Queue *queue) {
|
||||||
|
Process *current = queue->end;
|
||||||
|
while (current != NULL) {
|
||||||
|
Process *next = current->prev_elem;
|
||||||
|
destroyProcess(current);
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
free(queue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Queue *createQueue() {
|
||||||
|
Queue *queue = calloc(1, sizeof(Queue));
|
||||||
|
if (queue == NULL) {
|
||||||
|
printf("Error allocating memory for queue\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
queue->start = NULL;
|
||||||
|
queue->end = NULL;
|
||||||
|
queue->size = 0;
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
27
Assignment5/lib/queue.h
Normal file
27
Assignment5/lib/queue.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef QUEUE_H
|
||||||
|
#define QUEUE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
typedef struct Queue {
|
||||||
|
Process *start;
|
||||||
|
Process *end;
|
||||||
|
int size;
|
||||||
|
} Queue;
|
||||||
|
|
||||||
|
int contains(Queue *queue, char *username);
|
||||||
|
|
||||||
|
Process *search(Queue *queue, char *username);
|
||||||
|
|
||||||
|
void enqueue(Queue *queue, Process *process);
|
||||||
|
|
||||||
|
Process *dequeue(Queue *queue);
|
||||||
|
|
||||||
|
void printList(Queue *queue);
|
||||||
|
|
||||||
|
int stop(Queue *queue);
|
||||||
|
|
||||||
|
Queue* createQueue();
|
||||||
|
|
||||||
|
#endif //QUEUE_H
|
6
Assignment5/main.c
Normal file
6
Assignment5/main.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("Hello, World!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
101
Assignment5/round_robin.c
Normal file
101
Assignment5/round_robin.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "lib/queue.h"
|
||||||
|
|
||||||
|
#define MAX_USERNAME_LENGTH 100
|
||||||
|
int QUANTUM;
|
||||||
|
|
||||||
|
Queue *input_queue() {
|
||||||
|
Queue *queue = createQueue();
|
||||||
|
char username[MAX_USERNAME_LENGTH]; // username buffer
|
||||||
|
char job;
|
||||||
|
int arrival_time, duration;
|
||||||
|
|
||||||
|
scanf("%d", &QUANTUM);
|
||||||
|
while (getchar() != '\n'); // clear the newline from the buffer
|
||||||
|
while (getchar() != '\n'); // ignore the rest of the line, this is the table line
|
||||||
|
|
||||||
|
// Loop through the process table and enqueue each process
|
||||||
|
while (scanf("%99s %c %d %d", username, &job, &arrival_time, &duration) != EOF) {
|
||||||
|
Process *process = createProcess(username, job, arrival_time, duration);
|
||||||
|
enqueue(queue, process);
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void simulation(Queue *in_queue) {
|
||||||
|
// Summary creation
|
||||||
|
Process *process = in_queue->end;
|
||||||
|
Queue *summary_queue = createQueue();
|
||||||
|
for (int i = 0; i < in_queue->size; ++i) {
|
||||||
|
if (contains(summary_queue, process->username) == false) {
|
||||||
|
Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration);
|
||||||
|
enqueue(summary_queue, copy);
|
||||||
|
}
|
||||||
|
process = process->prev_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop variables
|
||||||
|
int quantum = QUANTUM;
|
||||||
|
int addedJobs = 0;
|
||||||
|
int time = 0;
|
||||||
|
|
||||||
|
// Create a queue for the simulation
|
||||||
|
Queue *sim_queue = createQueue();
|
||||||
|
|
||||||
|
printf("Time\tJob\n");
|
||||||
|
while (true) {
|
||||||
|
time++;
|
||||||
|
// Begin going through all jobs and enqueueing them if they have arrived
|
||||||
|
process = in_queue->end;
|
||||||
|
for (int i = 0; i < in_queue->size; i++) {
|
||||||
|
if (process->arrival_time == time) {
|
||||||
|
// Create copy to keep the queues separate
|
||||||
|
Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration);
|
||||||
|
enqueue(sim_queue, copy);
|
||||||
|
addedJobs++;
|
||||||
|
}
|
||||||
|
process = process->prev_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin printing the current job
|
||||||
|
process = sim_queue->end;
|
||||||
|
if (sim_queue->size == 0) { //If there is nothing in sim_queue, print "-"
|
||||||
|
printf("%d\t-\n", time);
|
||||||
|
if (addedJobs == in_queue->size) {
|
||||||
|
break; // If all jobs have been added, and the simulation queue is empty, then we are done
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("%d\t%c\n", time, process->job); // Print the current job
|
||||||
|
process->duration--;
|
||||||
|
quantum--;
|
||||||
|
if (process->duration == 0) { // If the process is done, delete it
|
||||||
|
Process *temp = dequeue(sim_queue); // Store the process in a temp variable for deletion
|
||||||
|
search(summary_queue, temp->username)->finish_time = time; // Set the finish time for the summary queue
|
||||||
|
destroyProcess(temp); // This should be called on every process
|
||||||
|
quantum = QUANTUM; // Make sure to reset the quantum when a process is done
|
||||||
|
} else if (quantum == 0) { // If the quantum is 0, then we need to dequeue the process and enqueue it again
|
||||||
|
process = dequeue(sim_queue);
|
||||||
|
enqueue(sim_queue, process);
|
||||||
|
quantum = QUANTUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the summary
|
||||||
|
printf("\nSummary\n");
|
||||||
|
printList(summary_queue);
|
||||||
|
|
||||||
|
// Free memory for the simulation queue. There should be nothing left in it
|
||||||
|
stop(sim_queue);
|
||||||
|
|
||||||
|
// We never dequeue from the summary queue, so we don't need to make sure about freeing dequeued processes
|
||||||
|
stop(summary_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Queue *in_queue = input_queue(); // Create the input queue
|
||||||
|
simulation(in_queue); // Run simulation on input queue
|
||||||
|
stop(in_queue); // Free memory for input queue
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user