Make a5 better?
This commit is contained in:
parent
3eaf16e12b
commit
d4f9dd0c5b
7
Assignment5/Process.md
Normal file
7
Assignment5/Process.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
1. The print sem is initialized to 0, because the print needs to first wait for the first simulation tick to happen.
|
||||||
|
2. The simulation sem is initialized to the number of cpus, since each cpu needs to tick once before the print can happen.
|
||||||
|
3. The simulation on each cpu is started, and at the end of each simulation, the sim thread will post to the print sem, so the print thread can print the results. The sim thread will now wait for the print sem, since it needs to wait for the print to finish before it can start the next simulation.
|
||||||
|
4. The print thread will wait on the sim sem for each CPU thread, and this should leave the sem at 0 again.
|
||||||
|
5. At the end of the print function, before the simulation is allowed to print again, the print thread will increase the time, and then post to the sim sem for each CPU thread, so the simulation can start again.
|
||||||
|
6. Repeat steps 3-5 until the simulation is done.
|
||||||
|
7.
|
@ -1,7 +1,7 @@
|
|||||||
2
|
2
|
||||||
3 2
|
3 2
|
||||||
User Process Arrival Duration Affinity
|
User Process Arrival Duration Affinity
|
||||||
Jim A 2 5 0
|
Jim A 2 5 0
|
||||||
Mary B 2 2 1
|
Mary B 2 2 1
|
||||||
Sue C 5 5 1
|
Sue C 5 5 1
|
||||||
Mary D 6 2 0
|
Mary D 6 2 0
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
2
|
2
|
||||||
3 2
|
3 2
|
||||||
User Process Arrival Duration Affinity
|
User Process Arrival Duration Affinity
|
||||||
Jim A 2 5 0
|
Jim A 2 5 0
|
||||||
Mary B 2 2 1
|
Mary B 2 2 1
|
||||||
Mary C 3 4 1
|
Mary C 3 4 1
|
||||||
Sue D 5 5 1
|
Sue D 5 5 1
|
||||||
Mary E 6 2 0
|
Mary E 6 2 0
|
||||||
|
@ -8,19 +8,15 @@
|
|||||||
int *QUANTUM;
|
int *QUANTUM;
|
||||||
int CPUS;
|
int CPUS;
|
||||||
|
|
||||||
// Semaphore for the threads to simulate
|
|
||||||
sem_t print_sem;
|
sem_t print_sem;
|
||||||
|
|
||||||
sem_t sim_sem;
|
sem_t sim_sem;
|
||||||
|
|
||||||
// Mutex for thread finish count
|
|
||||||
pthread_mutex_t finish_mutex;
|
pthread_mutex_t finish_mutex;
|
||||||
int finish_count = 0;
|
|
||||||
|
|
||||||
// Mutex for global time
|
|
||||||
pthread_mutex_t time_mutex;
|
pthread_mutex_t time_mutex;
|
||||||
int TIME = 1;
|
|
||||||
|
|
||||||
|
pthread_mutex_t summary_mutex;
|
||||||
|
|
||||||
|
int finish_count = 0;
|
||||||
|
int TIME = 1;
|
||||||
typedef struct ThreadArgs {
|
typedef struct ThreadArgs {
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
char *print_buffer;
|
char *print_buffer;
|
||||||
@ -94,7 +90,6 @@ 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;
|
|
||||||
|
|
||||||
// Print the Time label as well as the CPU labels
|
// Print the Time label as well as the CPU labels
|
||||||
printf("Time");
|
printf("Time");
|
||||||
@ -103,9 +98,11 @@ void *print(void *args) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
while (true) {
|
bool finished = false;
|
||||||
|
|
||||||
|
while (finished == false) {
|
||||||
// Wait for all the simulation threads to finish
|
// Wait for all the simulation threads to finish
|
||||||
for (int i = 0; i < CPUS - getFinishCount(); ++i) {
|
for (int i = getFinishCount(); i < CPUS; ++i) {
|
||||||
sem_wait(&print_sem);
|
sem_wait(&print_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,22 +117,23 @@ void *print(void *args) {
|
|||||||
|
|
||||||
// Check if every process is done
|
// Check if every process is done
|
||||||
if (getFinishCount() == CPUS) {
|
if (getFinishCount() == CPUS) {
|
||||||
break;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Essentially increase the time right before simulating
|
// Essentially increase the time right before simulating
|
||||||
incrementTime();
|
incrementTime();
|
||||||
|
|
||||||
// Increment the simulation semaphore to let the simulation threads run
|
// Increment the simulation semaphore to let the simulation threads run
|
||||||
for (int i = 0; i < CPUS - getFinishCount(); ++i) {
|
for (int i = getFinishCount(); i < CPUS; ++i) {
|
||||||
sem_post(&sim_sem);
|
sem_post(&sim_sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the summary
|
// Print the summary
|
||||||
printf("\nSummary\n");
|
printf("\nSummary\n");
|
||||||
printList(summary_queue);
|
pthread_mutex_lock(&summary_mutex);
|
||||||
|
printList(thread_args->summary_queue);
|
||||||
|
pthread_mutex_unlock(&summary_mutex);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +150,7 @@ void *simulation(void *args) {
|
|||||||
int quantum = QUANTUM[cpu_id];
|
int quantum = QUANTUM[cpu_id];
|
||||||
int addedJobs = 0;
|
int addedJobs = 0;
|
||||||
int numberOfJobsForThisCPU = 0;
|
int numberOfJobsForThisCPU = 0;
|
||||||
|
int time = 0;
|
||||||
int previousTime;
|
int previousTime;
|
||||||
Process *process = NULL;
|
Process *process = NULL;
|
||||||
|
|
||||||
@ -165,11 +163,10 @@ void *simulation(void *args) {
|
|||||||
process = process->prev_elem;
|
process = process->prev_elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
int time = 0;
|
bool finished = false;
|
||||||
|
|
||||||
// Create a queue for the simulation
|
// Create a queue for the simulation
|
||||||
Queue *sim_queue = createQueue();
|
Queue *sim_queue = createQueue();
|
||||||
while (true) {
|
while (finished == false) {
|
||||||
// Only simulate if the time has changed
|
// Only simulate if the time has changed
|
||||||
previousTime = time;
|
previousTime = time;
|
||||||
time = getTime();
|
time = getTime();
|
||||||
@ -189,18 +186,15 @@ void *simulation(void *args) {
|
|||||||
|
|
||||||
// Begin printing the current job
|
// Begin printing the current job
|
||||||
process = sim_queue->end;
|
process = sim_queue->end;
|
||||||
if (sim_queue->size == 0) { //If there is nothing in sim_queue, put '-' in the print buffer
|
if (sim_queue->size != 0) {
|
||||||
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 {
|
|
||||||
print_buffer[cpu_id] = process->job;
|
print_buffer[cpu_id] = process->job;
|
||||||
process->duration--;
|
process->duration--;
|
||||||
quantum--;
|
quantum--;
|
||||||
if (process->duration == 0) { // If the process is done, delete it
|
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
|
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
|
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
|
destroyProcess(temp); // This should be called on every process
|
||||||
quantum = QUANTUM[cpu_id]; // 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
|
} else if (quantum == 0) { // If the quantum is 0, then we need to dequeue the process and enqueue it again
|
||||||
@ -208,6 +202,11 @@ void *simulation(void *args) {
|
|||||||
enqueue(sim_queue, process);
|
enqueue(sim_queue, process);
|
||||||
quantum = QUANTUM[cpu_id];
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Allow the print thread to print because the simulation for this tick is done
|
// Allow the print thread to print because the simulation for this tick is done
|
||||||
sem_post(&print_sem);
|
sem_post(&print_sem);
|
||||||
@ -215,11 +214,8 @@ void *simulation(void *args) {
|
|||||||
}
|
}
|
||||||
// Free memory for the simulation queue. There should be nothing left in it
|
// Free memory for the simulation queue. There should be nothing left in it
|
||||||
stop(sim_queue);
|
stop(sim_queue);
|
||||||
|
|
||||||
// Signal that the thread is done
|
// Signal that the thread is done
|
||||||
incrementFinishCount();
|
incrementFinishCount();
|
||||||
// Allow the print thread to print one last time
|
|
||||||
sem_post(&print_sem);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,6 +229,7 @@ int main() {
|
|||||||
sem_init(&sim_sem, 0, CPUS); // Initialize the semaphore
|
sem_init(&sim_sem, 0, CPUS); // Initialize the semaphore
|
||||||
pthread_mutex_init(&finish_mutex, NULL); // Initialize the mutex
|
pthread_mutex_init(&finish_mutex, NULL); // Initialize the mutex
|
||||||
pthread_mutex_init(&time_mutex, NULL); // Initialize the mutex
|
pthread_mutex_init(&time_mutex, NULL); // Initialize the mutex
|
||||||
|
pthread_mutex_init(&summary_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
|
||||||
@ -246,6 +243,10 @@ int main() {
|
|||||||
}
|
}
|
||||||
process = process->prev_elem;
|
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
|
// Create the simulation threads
|
||||||
pthread_t threads[CPUS];
|
pthread_t threads[CPUS];
|
||||||
@ -255,19 +256,13 @@ int main() {
|
|||||||
pthread_create(&threads[i], NULL, &simulation, args[i]);
|
pthread_create(&threads[i], NULL, &simulation, args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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
|
// Threads simulate, then print
|
||||||
for (int i = 0; i < CPUS; i++) {
|
for (int i = 0; i < CPUS; i++) {
|
||||||
pthread_join(threads[i], NULL);
|
pthread_join(threads[i], NULL);
|
||||||
free(args[i]);
|
free(args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait for print thread to finish
|
||||||
pthread_join(print_thread, NULL);
|
pthread_join(print_thread, NULL);
|
||||||
free(print_args);
|
free(print_args);
|
||||||
|
|
||||||
|
16
Assignment5/testing/output2.txt
Normal file
16
Assignment5/testing/output2.txt
Normal 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
|
32
Assignment5/testing/output3-1.txt
Normal file
32
Assignment5/testing/output3-1.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
Time CPU0 CPU1
|
||||||
|
finish count: 0
|
||||||
|
1 - -
|
||||||
|
finish count: 0
|
||||||
|
2 A B
|
||||||
|
finish count: 0
|
||||||
|
3 A B
|
||||||
|
finish count: 0
|
||||||
|
4 A C
|
||||||
|
finish count: 0
|
||||||
|
5 A C
|
||||||
|
finish count: 0
|
||||||
|
6 A D
|
||||||
|
finish count: 0
|
||||||
|
7 E D
|
||||||
|
finish count: 0
|
||||||
|
8 E C
|
||||||
|
finish count: 1
|
||||||
|
9 - C
|
||||||
|
finish count: 1
|
||||||
|
10 - D
|
||||||
|
finish count: 1
|
||||||
|
11 - D
|
||||||
|
finish count: 1
|
||||||
|
12 - D
|
||||||
|
finish count: 1
|
||||||
|
13 - -
|
||||||
|
|
||||||
|
Summary
|
||||||
|
Jim 6
|
||||||
|
Mary 9
|
||||||
|
Sue 12
|
19
Assignment5/testing/output3-2.txt
Normal file
19
Assignment5/testing/output3-2.txt
Normal 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
|
19
Assignment5/testing/output3.txt
Normal file
19
Assignment5/testing/output3.txt
Normal 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
|
14
Assignment5/testing/test2.sh
Normal file
14
Assignment5/testing/test2.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Do this forever
|
||||||
|
while true; do
|
||||||
|
# Capture output of the command
|
||||||
|
output=$(../build/Assignment5 < ../documentation/a5_sample_input_2.txt)
|
||||||
|
# compare against output3.txt
|
||||||
|
if [ "$output" != "$(cat output2.txt)" ]; then
|
||||||
|
echo "Test 2 failed"
|
||||||
|
# show output
|
||||||
|
echo "$output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
14
Assignment5/testing/test3.sh
Normal file
14
Assignment5/testing/test3.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Do this forever
|
||||||
|
while true; do
|
||||||
|
# Capture output of the command
|
||||||
|
output=$(../build/Assignment5 < ../documentation/a5_sample_input_3.txt)
|
||||||
|
# compare against output3.txt
|
||||||
|
if [ "$output" != "$(cat output3.txt)" ]; then
|
||||||
|
echo "Test 3 failed"
|
||||||
|
# show output
|
||||||
|
echo "$output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
Loading…
Reference in New Issue
Block a user