Add working? solution
This commit is contained in:
parent
3b149882ee
commit
64d3af7762
@ -1,7 +1,7 @@
|
|||||||
1
|
1
|
||||||
3
|
3
|
||||||
User Process Arrival Duration Affinity
|
User Process Arrival Duration Affinity
|
||||||
Jim A 2 5 0
|
Jim A 2 5 0
|
||||||
Mary B 2 2 0
|
Mary B 2 2 0
|
||||||
Sue C 5 5 0
|
Sue C 5 5 0
|
||||||
Mary D 6 2 0
|
Mary D 6 2 0
|
||||||
|
@ -8,25 +8,26 @@
|
|||||||
|
|
||||||
// TODO: Need to use semaphore for thread synchronization, and mutex for shared variables
|
// 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
|
#define MAX_USERNAME_LENGTH 100
|
||||||
int QUANTUM;
|
int QUANTUM;
|
||||||
int CPUS;
|
int CPUS;
|
||||||
int TIME = 0;
|
|
||||||
|
|
||||||
// Semaphore for the threads to simulate
|
// Semaphore for the threads to simulate
|
||||||
sem_t sim_sem;
|
|
||||||
|
|
||||||
// Semaphore for the thread to control printing
|
|
||||||
sem_t print_sem;
|
sem_t print_sem;
|
||||||
|
|
||||||
// Mutex for simulation
|
sem_t sim_sem;
|
||||||
pthread_mutex_t sim_mutex;
|
|
||||||
|
|
||||||
// Mutex for thread finish count
|
// Mutex for thread finish count
|
||||||
pthread_mutex_t finish_mutex;
|
pthread_mutex_t finish_mutex;
|
||||||
int finish_count = 0;
|
int finish_count = 0;
|
||||||
|
|
||||||
|
// Mutex for global time
|
||||||
|
pthread_mutex_t time_mutex;
|
||||||
|
int TIME = 1;
|
||||||
|
|
||||||
typedef struct ThreadArgs {
|
typedef struct ThreadArgs {
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
char *print_buffer;
|
char *print_buffer;
|
||||||
@ -64,6 +65,18 @@ Queue *input_queue() {
|
|||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getTime() {
|
||||||
|
pthread_mutex_lock(&time_mutex);
|
||||||
|
int time = TIME;
|
||||||
|
pthread_mutex_unlock(&time_mutex);
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
void incrementTime() {
|
||||||
|
pthread_mutex_lock(&time_mutex);
|
||||||
|
TIME++;
|
||||||
|
pthread_mutex_unlock(&time_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -78,38 +91,29 @@ void *print(void *args) {
|
|||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
int test = 0;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
pthread_mutex_lock(&sim_mutex);
|
sem_wait(&print_sem);
|
||||||
if (finish_count == CPUS) {
|
int time = getTime();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%d", TIME);
|
|
||||||
|
|
||||||
|
// Print the time and the print buffer
|
||||||
|
printf("%d", time);
|
||||||
for (int i = 0; i < CPUS; ++i) {
|
for (int i = 0; i < CPUS; ++i) {
|
||||||
// Allow the simulation to begin
|
printf("\t%c", print_buffer[i]);
|
||||||
//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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
TIME++;
|
|
||||||
|
// Check if every process is done
|
||||||
|
if (finish_count == CPUS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementTime();
|
||||||
|
|
||||||
|
// Increment the simulation semaphore to let the simulation threads run
|
||||||
|
for (int i = 0; i < CPUS; ++i) {
|
||||||
|
sem_post(&sim_sem);
|
||||||
|
}
|
||||||
|
|
||||||
test++;
|
|
||||||
if (test == 35) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&sim_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the summary
|
// Print the summary
|
||||||
@ -128,22 +132,31 @@ void *simulation(void *args) {
|
|||||||
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;
|
||||||
|
int numberOfJobsForThisCPU = 0;
|
||||||
|
|
||||||
|
// Count number of jobs this CPU has to do
|
||||||
|
process = in_queue->end;
|
||||||
|
for (int i = 0; i < in_queue->size; ++i) {
|
||||||
|
if (process->affinity == cpu_id) {
|
||||||
|
numberOfJobsForThisCPU++;
|
||||||
|
}
|
||||||
|
process = process->prev_elem;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a queue for the simulation
|
// Create a queue for the simulation
|
||||||
Queue *sim_queue = createQueue();
|
Queue *sim_queue = createQueue();
|
||||||
while (true) {
|
while (true) {
|
||||||
pthread_mutex_lock(&sim_mutex);
|
sem_wait(&sim_sem);
|
||||||
|
int time = getTime();
|
||||||
|
|
||||||
//sem_wait(&sim_sem); // Wait for the thread to be allowed to start
|
|
||||||
// Begin going through all jobs and enqueueing them if they have arrived
|
// Begin going through all jobs and enqueueing them if they have arrived
|
||||||
process = in_queue->end;
|
process = in_queue->end;
|
||||||
for (int i = 0; i < in_queue->size; i++) {
|
for (int i = 0; i < in_queue->size; i++) {
|
||||||
if (process->affinity == cpu_id && process->arrival_time == TIME) {
|
if (process->affinity == cpu_id && process->arrival_time == time) {
|
||||||
// Create copy to keep the queues separate
|
// Create copy to keep the queues separate
|
||||||
Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration, process->affinity);
|
Process *copy = createProcess(process->username, process->job, process->arrival_time, process->duration, process->affinity);
|
||||||
enqueue(sim_queue, copy);
|
enqueue(sim_queue, copy);
|
||||||
@ -156,7 +169,8 @@ void *simulation(void *args) {
|
|||||||
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) { //If there is nothing in sim_queue, put '-' in the print buffer
|
||||||
print_buffer[cpu_id] = '-';
|
print_buffer[cpu_id] = '-';
|
||||||
if (addedJobs == in_queue->size) {
|
if (addedJobs >= numberOfJobsForThisCPU) {
|
||||||
|
|
||||||
break; // If all jobs have been added, and the simulation queue is empty, then we are done
|
break; // If all jobs have been added, and the simulation queue is empty, then we are done
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -165,7 +179,7 @@ void *simulation(void *args) {
|
|||||||
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
|
||||||
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
|
||||||
destroyProcess(temp); // This should be called on every process
|
destroyProcess(temp); // This should be called on every process
|
||||||
quantum = QUANTUM; // Make sure to reset the quantum when a process is done
|
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
|
} else if (quantum == 0) { // If the quantum is 0, then we need to dequeue the process and enqueue it again
|
||||||
@ -175,8 +189,7 @@ void *simulation(void *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Allow the print thread to print
|
// Allow the print thread to print
|
||||||
//sem_post(&print_sem);
|
sem_post(&print_sem);
|
||||||
pthread_mutex_unlock(&sim_mutex);
|
|
||||||
}
|
}
|
||||||
// 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);
|
||||||
@ -185,7 +198,8 @@ void *simulation(void *args) {
|
|||||||
pthread_mutex_lock(&finish_mutex);
|
pthread_mutex_lock(&finish_mutex);
|
||||||
finish_count++;
|
finish_count++;
|
||||||
pthread_mutex_unlock(&finish_mutex);
|
pthread_mutex_unlock(&finish_mutex);
|
||||||
|
// Allow the print thread to print one last time
|
||||||
|
sem_post(&print_sem);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,10 +209,10 @@ int main() {
|
|||||||
Queue *in_queue = input_queue(); // Create the input queue
|
Queue *in_queue = input_queue(); // Create the input queue
|
||||||
|
|
||||||
// Make sure sem is init right after getting cpus, which is done in 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
|
||||||
//sem_init(&print_sem, 0, 0); // 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(&sim_mutex, NULL); // Initialize the mutex
|
pthread_mutex_init(&time_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
|
||||||
|
Loading…
Reference in New Issue
Block a user