Work on a5

This commit is contained in:
Isaac Shoebottom 2023-10-30 12:21:07 -03:00
parent 72ab0d8fe9
commit 3b149882ee
6 changed files with 181 additions and 81 deletions

View File

@ -1,7 +1,7 @@
1 1
3 3
User Process Arrival Duration User Process Arrival Duration Affinity
Jim A 2 5 Jim A 2 5 0
Mary B 2 2 Mary B 2 2 0
Sue C 5 5 Sue C 5 5 0
Mary D 6 2 Mary D 6 2 0

View File

@ -0,0 +1,7 @@
2
3 2
User Process Arrival Duration Affinity
Jim A 2 5 0
Mary B 2 2 1
Sue C 5 5 1
Mary D 6 2 0

View File

@ -0,0 +1,8 @@
2
3 2
User Process Arrival Duration Affinity
Jim A 2 5 0
Mary B 2 2 1
Mary C 3 4 1
Sue D 5 5 1
Mary E 6 2 0

View File

@ -0,0 +1,16 @@
Time CPU0 CPU1
1 - -
2 A B
3 A B
4 A -
5 A C
6 A C
7 D C
8 D C
9 - C
10 - -
Summary
Jim 6
Mary 8
Sue 9

View File

@ -0,0 +1,19 @@
Time CPU0 CPU1
1 - -
2 A B
3 A B
4 A C
5 A C
6 A D
7 E D
8 E C
9 - C
10 - D
11 - D
12 - D
13 - -
Summary
Jim 6
Mary 9
Sue 12

View File

@ -6,14 +6,26 @@
// TODO: Look into semaphore increment too much in print function, look into synchronization // TODO: Look into semaphore increment too much in print function, look into synchronization
// TODO: Need to use semaphore for thread synchronization, and mutex for shared variables
#define MAX_USERNAME_LENGTH 100 #define MAX_USERNAME_LENGTH 100
int QUANTUM; int QUANTUM;
int CPUS; int CPUS;
int TIME = 0; int TIME = 0;
// Semaphore for the print function // Semaphore for the threads to simulate
sem_t print_semaphore; sem_t sim_sem;
// Semaphore for the thread to control printing
sem_t print_sem;
// Mutex for simulation
pthread_mutex_t sim_mutex;
// Mutex for thread finish count
pthread_mutex_t finish_mutex;
int finish_count = 0;
typedef struct ThreadArgs { typedef struct ThreadArgs {
int cpu_id; int cpu_id;
@ -22,7 +34,7 @@ typedef struct ThreadArgs {
Queue *in_queue; Queue *in_queue;
} ThreadArgs; } ThreadArgs;
ThreadArgs *createArgs(int cpu_id, char* print_buffer, Queue *summary_queue, Queue *in_queue) { ThreadArgs *createArgs(int cpu_id, char *print_buffer, Queue *summary_queue, Queue *in_queue) {
ThreadArgs *args = malloc(sizeof(ThreadArgs)); ThreadArgs *args = malloc(sizeof(ThreadArgs));
args->cpu_id = cpu_id; args->cpu_id = cpu_id;
args->print_buffer = print_buffer; args->print_buffer = print_buffer;
@ -32,32 +44,29 @@ ThreadArgs *createArgs(int cpu_id, char* print_buffer, Queue *summary_queue, Que
} }
Queue *input_queue() { Queue *input_queue() {
Queue *queue = createQueue(); Queue *queue = createQueue();
char username[MAX_USERNAME_LENGTH]; // username buffer char username[MAX_USERNAME_LENGTH]; // username buffer
char job; char job;
int arrival_time, duration, affinity; int arrival_time, duration, affinity;
scanf("%d", &QUANTUM);
while (getchar() != '\n'); // clear the newline from the buffer
scanf("%d", &CPUS); scanf("%d", &CPUS);
while (getchar() != '\n'); // clear the newline from the buffer while (getchar() != '\n'); // clear the newline from the buffer
// Make sure sem is init right after getting cpus scanf("%d", &QUANTUM);
sem_init(&print_semaphore, 0, CPUS); // Initialize the semaphore while (getchar() != '\n'); // clear the newline from the buffer
while (getchar() != '\n'); // ignore the rest of the line, this is the table line while (getchar() != '\n'); // ignore the rest of the line, this is the table line
// Loop through the process table and enqueue each process // Loop through the process table and enqueue each process
while (scanf("%99s %c %d %d %d", username, &job, &arrival_time, &duration, &affinity) != EOF) { while (scanf("%99s %c %d %d %d", username, &job, &arrival_time, &duration, &affinity) != EOF) {
Process *process = createProcess(username, job, arrival_time, duration, affinity); Process *process = createProcess(username, job, arrival_time, duration, affinity);
enqueue(queue, process); enqueue(queue, process);
} }
return queue; return queue;
} }
void* print(void *args) { void *print(void *args) {
// Cast args and create local variables // Cast args and create local variables
ThreadArgs *thread_args = (ThreadArgs*) args; ThreadArgs *thread_args = (ThreadArgs *) args;
char *print_buffer = thread_args->print_buffer; char *print_buffer = thread_args->print_buffer;
Queue *summary_queue = thread_args->summary_queue; Queue *summary_queue = thread_args->summary_queue;
Queue *in_queue = thread_args->in_queue; Queue *in_queue = thread_args->in_queue;
@ -69,15 +78,38 @@ void* print(void *args) {
} }
printf("\n"); printf("\n");
for (int i = 0; i < in_queue->size; ++i) { int test = 0;
TIME++;
// Allow the simulation to begin while (true) {
sem_post(&print_semaphore); pthread_mutex_lock(&sim_mutex);
if (finish_count == CPUS) {
break;
}
printf("%d", TIME);
for (int i = 0; i < CPUS; ++i) {
// Allow the simulation to begin
//sem_post(&sim_sem);
// Wait for the simulation to finish
//sem_wait(&print_sem);
for (int j = 0; j < CPUS; ++j) {
printf("\t%c", print_buffer[j]);
}
for (int j = 0; j < CPUS; ++j) {
printf("%d\t%c", TIME, print_buffer[i]);
} }
printf("\n"); printf("\n");
TIME++;
test++;
if (test == 35) {
break;
}
pthread_mutex_unlock(&sim_mutex);
} }
// Print the summary // Print the summary
@ -88,68 +120,86 @@ void* print(void *args) {
} }
void* simulation(void *args) { void *simulation(void *args) {
// Cast args and create local variables // Cast args and create local variables
ThreadArgs *thread_args = (ThreadArgs*) args; ThreadArgs *thread_args = (ThreadArgs *) args;
Queue *in_queue = thread_args->in_queue; Queue *in_queue = thread_args->in_queue;
Queue *summary_queue = thread_args->summary_queue; Queue *summary_queue = thread_args->summary_queue;
char *print_buffer = thread_args->print_buffer; char *print_buffer = thread_args->print_buffer;
int cpu_id = thread_args->cpu_id; int cpu_id = thread_args->cpu_id;
// Loop variables // Loop variables
int quantum = QUANTUM; int quantum = QUANTUM;
int addedJobs = 0; int addedJobs = 0;
Process *process = NULL; Process *process = NULL;
// Create a queue for the simulation // Create a queue for the simulation
Queue *sim_queue = createQueue(); Queue *sim_queue = createQueue();
while (true) { while (true) {
sem_wait(&print_semaphore); // Wait for the print semaphore pthread_mutex_lock(&sim_mutex);
// 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->affinity == cpu_id && process->arrival_time == TIME) {
// Create copy to keep the queues separate
Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration, process->affinity);
enqueue(sim_queue, copy);
addedJobs++;
}
process = process->prev_elem;
}
// Begin printing the current job //sem_wait(&sim_sem); // Wait for the thread to be allowed to start
process = sim_queue->end; // Begin going through all jobs and enqueueing them if they have arrived
if (sim_queue->size == 0) { //If there is nothing in sim_queue, put '-' in the print buffer process = in_queue->end;
print_buffer[cpu_id] = '-'; for (int i = 0; i < in_queue->size; i++) {
if (addedJobs == in_queue->size) { if (process->affinity == cpu_id && process->arrival_time == TIME) {
break; // If all jobs have been added, and the simulation queue is empty, then we are done // Create copy to keep the queues separate
} Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration, process->affinity);
} else { enqueue(sim_queue, copy);
print_buffer[cpu_id] = process->job; addedJobs++;
process->duration--; }
quantum--; process = process->prev_elem;
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 // Begin printing the current job
destroyProcess(temp); // This should be called on every process process = sim_queue->end;
quantum = QUANTUM; // Make sure to reset the quantum when a process is done if (sim_queue->size == 0) { //If there is nothing in sim_queue, put '-' in the print buffer
} else if (quantum == 0) { // If the quantum is 0, then we need to dequeue the process and enqueue it again print_buffer[cpu_id] = '-';
process = dequeue(sim_queue); if (addedJobs == in_queue->size) {
enqueue(sim_queue, process); break; // If all jobs have been added, and the simulation queue is empty, then we are done
quantum = QUANTUM; }
} } else {
} print_buffer[cpu_id] = process->job;
} process->duration--;
// Free memory for the simulation queue. There should be nothing left in it quantum--;
stop(sim_queue); 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;
}
}
// Allow the print thread to print
//sem_post(&print_sem);
pthread_mutex_unlock(&sim_mutex);
}
// Free memory for the simulation queue. There should be nothing left in it
stop(sim_queue);
// Signal that the thread is done
pthread_mutex_lock(&finish_mutex);
finish_count++;
pthread_mutex_unlock(&finish_mutex);
return NULL; return NULL;
} }
int main() { int main() {
Queue *in_queue = input_queue(); // Create the input queue setvbuf(stdout, NULL, _IONBF, 0);
Queue *in_queue = input_queue(); // Create the input queue
// Make sure sem is init right after getting cpus, which is done in input_queue
//sem_init(&sim_sem, 0, CPUS); // Initialize the semaphore
//sem_init(&print_sem, 0, 0); // Initialize the semaphore
pthread_mutex_init(&finish_mutex, NULL); // Initialize the mutex
pthread_mutex_init(&sim_mutex, NULL); // Initialize the mutex
Queue *summary_queue = createQueue(); // Create the summary queue Queue *summary_queue = createQueue(); // Create the summary queue
char *print_buffer = malloc(sizeof(char) * CPUS); // Create the print buffer char *print_buffer = malloc(sizeof(char) * CPUS); // Create the print buffer
@ -170,7 +220,7 @@ int main() {
// Create the simulation threads // Create the simulation threads
pthread_t threads[CPUS]; pthread_t threads[CPUS];
ThreadArgs* args[CPUS]; // Array of arguments for each thread, so we can free them later ThreadArgs *args[CPUS]; // Array of arguments for each thread, so we can free them later
for (int i = 0; i < CPUS; i++) { for (int i = 0; i < CPUS; i++) {
args[i] = createArgs(i, print_buffer, summary_queue, in_queue); args[i] = createArgs(i, print_buffer, summary_queue, in_queue);
pthread_create(&threads[i], NULL, &simulation, args[i]); pthread_create(&threads[i], NULL, &simulation, args[i]);
@ -183,8 +233,8 @@ int main() {
pthread_join(threads[i], NULL); pthread_join(threads[i], NULL);
free(args[i]); free(args[i]);
} }
stop(in_queue); // Free memory for input queue stop(in_queue); // Free memory for input queue
stop(summary_queue); // Free memory for summary queue stop(summary_queue); // Free memory for summary queue
free(print_buffer); // Free memory for print buffer free(print_buffer); // Free memory for print buffer
return 0; return 0;
} }