Make a5 better?
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
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
 | 
			
		||||
Jim	    A	    2   	5	        0
 | 
			
		||||
Mary	B	    2	    2	        1
 | 
			
		||||
Sue	    C	    5	    5	        1
 | 
			
		||||
Mary	D	    6	    2	        0
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +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
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
@@ -8,19 +8,15 @@
 | 
			
		||||
int *QUANTUM;
 | 
			
		||||
int CPUS;
 | 
			
		||||
 | 
			
		||||
// Semaphore for the threads to simulate
 | 
			
		||||
sem_t print_sem;
 | 
			
		||||
 | 
			
		||||
sem_t sim_sem;
 | 
			
		||||
 | 
			
		||||
// Mutex for thread finish count
 | 
			
		||||
pthread_mutex_t finish_mutex;
 | 
			
		||||
int finish_count = 0;
 | 
			
		||||
 | 
			
		||||
// Mutex for global time
 | 
			
		||||
pthread_mutex_t time_mutex;
 | 
			
		||||
int TIME = 1;
 | 
			
		||||
 | 
			
		||||
pthread_mutex_t summary_mutex;
 | 
			
		||||
 | 
			
		||||
int finish_count = 0;
 | 
			
		||||
int TIME = 1;
 | 
			
		||||
typedef struct ThreadArgs {
 | 
			
		||||
	int cpu_id;
 | 
			
		||||
	char *print_buffer;
 | 
			
		||||
@@ -94,7 +90,6 @@ 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;
 | 
			
		||||
 | 
			
		||||
	// Print the Time label as well as the CPU labels
 | 
			
		||||
	printf("Time");
 | 
			
		||||
@@ -103,9 +98,11 @@ void *print(void *args) {
 | 
			
		||||
	}
 | 
			
		||||
	printf("\n");
 | 
			
		||||
 | 
			
		||||
	while (true) {
 | 
			
		||||
	bool finished = false;
 | 
			
		||||
 | 
			
		||||
	while (finished == false) {
 | 
			
		||||
		// 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -120,22 +117,23 @@ void *print(void *args) {
 | 
			
		||||
 | 
			
		||||
		// Check if every process is done
 | 
			
		||||
		if (getFinishCount() == CPUS) {
 | 
			
		||||
			break;
 | 
			
		||||
			finished = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Essentially increase the time right before simulating
 | 
			
		||||
		incrementTime();
 | 
			
		||||
 | 
			
		||||
		// 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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Print the summary
 | 
			
		||||
	printf("\nSummary\n");
 | 
			
		||||
	printList(summary_queue);
 | 
			
		||||
 | 
			
		||||
	pthread_mutex_lock(&summary_mutex);
 | 
			
		||||
	printList(thread_args->summary_queue);
 | 
			
		||||
	pthread_mutex_unlock(&summary_mutex);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +150,7 @@ void *simulation(void *args) {
 | 
			
		||||
	int quantum = QUANTUM[cpu_id];
 | 
			
		||||
	int addedJobs = 0;
 | 
			
		||||
	int numberOfJobsForThisCPU = 0;
 | 
			
		||||
 | 
			
		||||
	int time = 0;
 | 
			
		||||
	int previousTime;
 | 
			
		||||
	Process *process = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -165,11 +163,10 @@ void *simulation(void *args) {
 | 
			
		||||
		process = process->prev_elem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int time = 0;
 | 
			
		||||
 | 
			
		||||
	bool finished = false;
 | 
			
		||||
	// Create a queue for the simulation
 | 
			
		||||
	Queue *sim_queue = createQueue();
 | 
			
		||||
	while (true) {
 | 
			
		||||
	while (finished == false) {
 | 
			
		||||
		// Only simulate if the time has changed
 | 
			
		||||
		previousTime = time;
 | 
			
		||||
		time = getTime();
 | 
			
		||||
@@ -189,18 +186,15 @@ void *simulation(void *args) {
 | 
			
		||||
 | 
			
		||||
			// Begin printing the current job
 | 
			
		||||
			process = sim_queue->end;
 | 
			
		||||
			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 {
 | 
			
		||||
			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
 | 
			
		||||
@@ -208,6 +202,11 @@ void *simulation(void *args) {
 | 
			
		||||
					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
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// Allow the print thread to print because the simulation for this tick is done
 | 
			
		||||
			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
 | 
			
		||||
	stop(sim_queue);
 | 
			
		||||
 | 
			
		||||
	// Signal that the thread is done
 | 
			
		||||
	incrementFinishCount();
 | 
			
		||||
	// Allow the print thread to print one last time
 | 
			
		||||
	sem_post(&print_sem);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -233,6 +229,7 @@ int main() {
 | 
			
		||||
	sem_init(&sim_sem, 0, CPUS); // Initialize the semaphore
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	Queue *summary_queue = createQueue(); // Create the summary queue
 | 
			
		||||
	char *print_buffer = malloc(sizeof(char) * CPUS); // Create the print buffer
 | 
			
		||||
@@ -246,6 +243,10 @@ 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];
 | 
			
		||||
@@ -255,19 +256,13 @@ int main() {
 | 
			
		||||
		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
 | 
			
		||||
	for (int i = 0; i < CPUS; i++) {
 | 
			
		||||
		pthread_join(threads[i], NULL);
 | 
			
		||||
		free(args[i]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Wait for print thread to finish
 | 
			
		||||
	pthread_join(print_thread, NULL);
 | 
			
		||||
	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
 | 
			
		||||
		Reference in New Issue
	
	Block a user