Mostly correct solution
This commit is contained in:
parent
552f95fe99
commit
c3faf35400
@ -25,10 +25,9 @@ int *QUANTUM;
|
||||
int CPUS;
|
||||
|
||||
sem_t print_sem;
|
||||
sem_t sim_sem;
|
||||
sem_t *sim_sems;
|
||||
pthread_mutex_t finish_mutex;
|
||||
pthread_mutex_t time_mutex;
|
||||
|
||||
pthread_mutex_t summary_mutex;
|
||||
|
||||
int finish_count = 0;
|
||||
@ -115,11 +114,11 @@ void *print(void *args) {
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
bool finished = false;
|
||||
|
||||
while (finished == false) {
|
||||
while (getFinishCount() < CPUS) {
|
||||
// Wait for all the simulation threads to finish
|
||||
for (int i = getFinishCount(); i < CPUS; ++i) {
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
//printf("print wait cpu_id: %d\n", i);
|
||||
sem_wait(&print_sem);
|
||||
}
|
||||
|
||||
@ -132,17 +131,12 @@ void *print(void *args) {
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Check if every process is done
|
||||
if (getFinishCount() == CPUS) {
|
||||
finished = true;
|
||||
}
|
||||
|
||||
// Essentially increase the time right before simulating
|
||||
incrementTime();
|
||||
|
||||
// Increment the simulation semaphore to let the simulation threads run
|
||||
for (int i = getFinishCount(); i < CPUS; ++i) {
|
||||
sem_post(&sim_sem);
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
sem_post(&sim_sems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,6 +145,14 @@ void *print(void *args) {
|
||||
pthread_mutex_lock(&summary_mutex);
|
||||
printList(thread_args->summary_queue);
|
||||
pthread_mutex_unlock(&summary_mutex);
|
||||
|
||||
// let the simulation threads finish
|
||||
// for some reason, if this is not here, the simulation threads will not finish
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
sem_post(&sim_sems[i]);
|
||||
}
|
||||
|
||||
//printf("print thread done\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -167,8 +169,8 @@ void *simulation(void *args) {
|
||||
int quantum = QUANTUM[cpu_id];
|
||||
int addedJobs = 0;
|
||||
int numberOfJobsForThisCPU = 0;
|
||||
int time = 0;
|
||||
int previousTime;
|
||||
int time;
|
||||
bool doneSimulating = false;
|
||||
Process *process = NULL;
|
||||
|
||||
// Count number of jobs this CPU has to do
|
||||
@ -180,59 +182,65 @@ void *simulation(void *args) {
|
||||
process = process->prev_elem;
|
||||
}
|
||||
|
||||
bool finished = false;
|
||||
// Create a queue for the simulation
|
||||
Queue *sim_queue = createQueue();
|
||||
while (finished == false) {
|
||||
while (getFinishCount() < CPUS) {
|
||||
// Only simulate if the time has changed
|
||||
previousTime = time;
|
||||
time = getTime();
|
||||
if (previousTime != time) {
|
||||
sem_wait(&sim_sem);
|
||||
// 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++;
|
||||
//printf("sim wait cpu_id: %d\n", cpu_id);
|
||||
sem_wait(&sim_sems[cpu_id]);
|
||||
if (!doneSimulating) {
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
process = process->prev_elem;
|
||||
}
|
||||
|
||||
// Begin simulating the current job
|
||||
process = sim_queue->end;
|
||||
if (sim_queue->size != 0) {
|
||||
print_buffer[cpu_id] = process->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
|
||||
pthread_mutex_lock(&summary_mutex);
|
||||
search(summary_queue, temp->username)->finish_time = time; // Set the finish time for the summary queue
|
||||
pthread_mutex_unlock(&summary_mutex);
|
||||
destroyProcess(temp); // This should be called on every process
|
||||
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[cpu_id];
|
||||
}
|
||||
} else { //If there is nothing in sim_queue, put '-' in the print buffer
|
||||
print_buffer[cpu_id] = '-';
|
||||
if (addedJobs >= numberOfJobsForThisCPU) {
|
||||
finished = true; // If all jobs have been added, and the simulation queue is empty, then we are done
|
||||
// Begin simulating the current job
|
||||
process = sim_queue->end;
|
||||
if (sim_queue->size != 0) {
|
||||
print_buffer[cpu_id] = process->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
|
||||
pthread_mutex_lock(&summary_mutex);
|
||||
search(summary_queue, temp->username)->finish_time = time; // Set the finish time for the summary queue
|
||||
pthread_mutex_unlock(&summary_mutex);
|
||||
destroyProcess(temp); // This should be called on every process
|
||||
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[cpu_id];
|
||||
}
|
||||
} else { //If there is nothing in sim_queue, put '-' in the print buffer
|
||||
print_buffer[cpu_id] = '-';
|
||||
if (addedJobs >= numberOfJobsForThisCPU) {
|
||||
// Need to do this while finish is locked, otherwise the print thread will exit early
|
||||
incrementFinishCount();
|
||||
// If all jobs have been added, and the simulation queue is empty, then we are done
|
||||
doneSimulating = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Allow the print thread to print because the simulation for this tick is done
|
||||
sem_post(&print_sem);
|
||||
}
|
||||
//printf("sim post cpu_id: %d\n", cpu_id);
|
||||
}
|
||||
// Let the print thread one last time
|
||||
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
|
||||
incrementFinishCount();
|
||||
|
||||
//printf("sim thread done: %d\n", cpu_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -243,7 +251,13 @@ int main() {
|
||||
|
||||
// Make sure sem is init right after getting cpus, which is done in input_queue
|
||||
sem_init(&print_sem, 0, 0); // Initialize the semaphore
|
||||
sem_init(&sim_sem, 0, CPUS); // Initialize the semaphore
|
||||
|
||||
// Array of semaphores, one for each CPU
|
||||
sim_sems = malloc(sizeof(sem_t) * CPUS);
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
sem_init(&sim_sems[i], 0, 1);
|
||||
}
|
||||
|
||||
pthread_mutex_init(&finish_mutex, NULL); // Initialize the mutex
|
||||
pthread_mutex_init(&time_mutex, NULL); // Initialize the mutex
|
||||
pthread_mutex_init(&summary_mutex, NULL); // Initialize the mutex
|
||||
@ -273,19 +287,47 @@ int main() {
|
||||
pthread_create(&threads[i], NULL, &simulation, args[i]);
|
||||
}
|
||||
|
||||
// Wait for print thread to finish
|
||||
int r = pthread_join(print_thread, NULL);
|
||||
free(print_args);
|
||||
//printf("joined print thread\n");
|
||||
//printf("thread result: %d\n", r);
|
||||
|
||||
// Threads simulate, then print
|
||||
for (int i = 0; i < CPUS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
r = pthread_join(threads[i], NULL);
|
||||
//printf("joined sim thread: %d\n", i);
|
||||
//printf("thread result: %d\n", r);
|
||||
free(args[i]);
|
||||
}
|
||||
|
||||
// Wait for print thread to finish
|
||||
pthread_join(print_thread, NULL);
|
||||
free(print_args);
|
||||
|
||||
|
||||
// Stop semaphores
|
||||
for (int i = 0; i < CPUS; ++i) {
|
||||
sem_destroy(&sim_sems[i]);
|
||||
//printf("destroyed sim sem: %d\n", i);
|
||||
}
|
||||
free(sim_sems);
|
||||
sem_destroy(&print_sem);
|
||||
|
||||
|
||||
// Stop mutexes
|
||||
|
||||
pthread_mutex_unlock(&finish_mutex);
|
||||
pthread_mutex_unlock(&summary_mutex);
|
||||
pthread_mutex_unlock(&time_mutex);
|
||||
|
||||
|
||||
pthread_mutex_destroy(&finish_mutex);
|
||||
pthread_mutex_destroy(&summary_mutex);
|
||||
pthread_mutex_destroy(&time_mutex);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
49
Assignment5/testing/output3_3.txt
Normal file
49
Assignment5/testing/output3_3.txt
Normal file
@ -0,0 +1,49 @@
|
||||
Time CPU0 CPU1
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
1 - -
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
2 A B
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
3 A B
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
4 A C
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
5 A C
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
6 A D
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
7 E D
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
8 E C
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
9 - C
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
10 - D
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
11 - D
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
12 - D
|
||||
sim post cpu_id: 0
|
||||
sim post cpu_id: 1
|
||||
sim thread done: 1
|
||||
13 - -
|
||||
|
||||
Summary
|
||||
Jim 6
|
||||
Mary 9
|
||||
Sue 12
|
||||
print thread done
|
||||
sim post cpu_id: 0
|
||||
sim thread done: 0
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
counter=1
|
||||
|
||||
# Do this forever
|
||||
while true; do
|
||||
# Capture output of the command
|
||||
@ -11,5 +13,6 @@ while true; do
|
||||
echo "$output"
|
||||
exit 1
|
||||
fi
|
||||
echo "Test 2 passed"
|
||||
echo "Test 2 passed $counter times"
|
||||
counter=$((counter+1))
|
||||
done
|
10
Assignment5/testing/test2simple.sh
Normal file
10
Assignment5/testing/test2simple.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
counter=0
|
||||
|
||||
# Do this forever
|
||||
while true; do
|
||||
(../build/Assignment5 < ../documentation/a5_sample_input_2.txt)
|
||||
counter=$((counter+1))
|
||||
echo $counter
|
||||
done
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
counter=1
|
||||
|
||||
# Do this forever
|
||||
while true; do
|
||||
# Capture output of the command
|
||||
@ -11,4 +13,6 @@ while true; do
|
||||
echo "$output"
|
||||
exit 1
|
||||
fi
|
||||
echo "Test 3 passed $counter times"
|
||||
counter=$((counter+1))
|
||||
done
|
Loading…
Reference in New Issue
Block a user