Mostly working a5
This commit is contained in:
parent
64d3af7762
commit
3eaf16e12b
5
Assignment5/.idea/codeStyles/codeStyleConfig.xml
Normal file
5
Assignment5/.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
@ -4,15 +4,8 @@
|
||||
#include <stdlib.h>
|
||||
#include "lib/queue.h"
|
||||
|
||||
// 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
|
||||
|
||||
// Need to make sure both threads read time once, or only tick once per time increment
|
||||
|
||||
|
||||
#define MAX_USERNAME_LENGTH 100
|
||||
int QUANTUM;
|
||||
int *QUANTUM;
|
||||
int CPUS;
|
||||
|
||||
// Semaphore for the threads to simulate
|
||||
@ -53,7 +46,13 @@ Queue *input_queue() {
|
||||
scanf("%d", &CPUS);
|
||||
while (getchar() != '\n'); // clear the newline from the buffer
|
||||
|
||||
scanf("%d", &QUANTUM);
|
||||
// Allocate dynamic quantum array
|
||||
QUANTUM = malloc(sizeof(int) * CPUS);
|
||||
int i = 0;
|
||||
while (i < CPUS) {
|
||||
scanf("%d", &QUANTUM[i]);
|
||||
i++;
|
||||
}
|
||||
while (getchar() != '\n'); // clear the newline from the buffer
|
||||
|
||||
while (getchar() != '\n'); // ignore the rest of the line, this is the table line
|
||||
@ -71,18 +70,31 @@ int getTime() {
|
||||
pthread_mutex_unlock(&time_mutex);
|
||||
return time;
|
||||
}
|
||||
|
||||
void incrementTime() {
|
||||
pthread_mutex_lock(&time_mutex);
|
||||
TIME++;
|
||||
pthread_mutex_unlock(&time_mutex);
|
||||
}
|
||||
|
||||
int getFinishCount() {
|
||||
pthread_mutex_lock(&finish_mutex);
|
||||
int count = finish_count;
|
||||
pthread_mutex_unlock(&finish_mutex);
|
||||
return count;
|
||||
}
|
||||
|
||||
void incrementFinishCount() {
|
||||
pthread_mutex_lock(&finish_mutex);
|
||||
finish_count++;
|
||||
pthread_mutex_unlock(&finish_mutex);
|
||||
}
|
||||
|
||||
void *print(void *args) {
|
||||
// Cast args and create local variables
|
||||
ThreadArgs *thread_args = (ThreadArgs *) args;
|
||||
char *print_buffer = thread_args->print_buffer;
|
||||
Queue *summary_queue = thread_args->summary_queue;
|
||||
Queue *in_queue = thread_args->in_queue;
|
||||
|
||||
// Print the Time label as well as the CPU labels
|
||||
printf("Time");
|
||||
@ -92,7 +104,11 @@ void *print(void *args) {
|
||||
printf("\n");
|
||||
|
||||
while (true) {
|
||||
// Wait for all the simulation threads to finish
|
||||
for (int i = 0; i < CPUS - getFinishCount(); ++i) {
|
||||
sem_wait(&print_sem);
|
||||
}
|
||||
|
||||
int time = getTime();
|
||||
|
||||
// Print the time and the print buffer
|
||||
@ -103,17 +119,17 @@ void *print(void *args) {
|
||||
printf("\n");
|
||||
|
||||
// Check if every process is done
|
||||
if (finish_count == CPUS) {
|
||||
if (getFinishCount() == CPUS) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Essentially increase the time right before simulating
|
||||
incrementTime();
|
||||
|
||||
// Increment the simulation semaphore to let the simulation threads run
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
for (int i = 0; i < CPUS - getFinishCount(); ++i) {
|
||||
sem_post(&sim_sem);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Print the summary
|
||||
@ -133,11 +149,13 @@ void *simulation(void *args) {
|
||||
int cpu_id = thread_args->cpu_id;
|
||||
|
||||
// Loop variables
|
||||
int quantum = QUANTUM;
|
||||
int quantum = QUANTUM[cpu_id];
|
||||
int addedJobs = 0;
|
||||
Process *process = NULL;
|
||||
int numberOfJobsForThisCPU = 0;
|
||||
|
||||
int previousTime;
|
||||
Process *process = NULL;
|
||||
|
||||
// Count number of jobs this CPU has to do
|
||||
process = in_queue->end;
|
||||
for (int i = 0; i < in_queue->size; ++i) {
|
||||
@ -147,12 +165,16 @@ void *simulation(void *args) {
|
||||
process = process->prev_elem;
|
||||
}
|
||||
|
||||
int time = 0;
|
||||
|
||||
// Create a queue for the simulation
|
||||
Queue *sim_queue = createQueue();
|
||||
while (true) {
|
||||
// Only simulate if the time has changed
|
||||
previousTime = time;
|
||||
time = getTime();
|
||||
if (previousTime != time) {
|
||||
sem_wait(&sim_sem);
|
||||
int time = getTime();
|
||||
|
||||
// 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++) {
|
||||
@ -170,7 +192,6 @@ void *simulation(void *args) {
|
||||
if (sim_queue->size == 0) { //If there is nothing in sim_queue, put '-' in the print buffer
|
||||
print_buffer[cpu_id] = '-';
|
||||
if (addedJobs >= numberOfJobsForThisCPU) {
|
||||
|
||||
break; // If all jobs have been added, and the simulation queue is empty, then we are done
|
||||
}
|
||||
} else {
|
||||
@ -181,23 +202,22 @@ void *simulation(void *args) {
|
||||
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
|
||||
quantum = QUANTUM[cpu_id]; // 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;
|
||||
quantum = QUANTUM[cpu_id];
|
||||
}
|
||||
}
|
||||
// Allow the print thread to print
|
||||
// Allow the print thread to print because the simulation for this tick is done
|
||||
sem_post(&print_sem);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
incrementFinishCount();
|
||||
// Allow the print thread to print one last time
|
||||
sem_post(&print_sem);
|
||||
return NULL;
|
||||
@ -227,11 +247,6 @@ int main() {
|
||||
process = process->prev_elem;
|
||||
}
|
||||
|
||||
// Create the print thread
|
||||
pthread_t print_thread;
|
||||
ThreadArgs *print_args = createArgs(0, print_buffer, summary_queue, in_queue);
|
||||
pthread_create(&print_thread, NULL, &print, print_args);
|
||||
|
||||
// Create the simulation threads
|
||||
pthread_t threads[CPUS];
|
||||
ThreadArgs *args[CPUS]; // Array of arguments for each thread, so we can free them later
|
||||
@ -240,15 +255,25 @@ int main() {
|
||||
pthread_create(&threads[i], NULL, &simulation, args[i]);
|
||||
}
|
||||
|
||||
// This should make sure all threads are done simulating, as the print function exits after simulation is done
|
||||
pthread_join(print_thread, NULL);
|
||||
// Just to make sure all threads are done
|
||||
|
||||
// Create the print thread
|
||||
pthread_t print_thread;
|
||||
ThreadArgs *print_args = createArgs(0, print_buffer, summary_queue, in_queue);
|
||||
pthread_create(&print_thread, NULL, &print, print_args);
|
||||
|
||||
|
||||
|
||||
// Threads simulate, then print
|
||||
for (int i = 0; i < CPUS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
free(args[i]);
|
||||
}
|
||||
pthread_join(print_thread, NULL);
|
||||
free(print_args);
|
||||
|
||||
stop(in_queue); // Free memory for input queue
|
||||
stop(summary_queue); // Free memory for summary queue
|
||||
free(print_buffer); // Free memory for print buffer
|
||||
free(QUANTUM); // Free memory for quantum array
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user