/** Removes all instances of ptr from the queue. This function should not use the comparer function, but check if the data contained in each element of the queue is equal (==) to ptr. @param q a pointer to an instance of the priqueue_t data structure @param ptr address of element to be removed @return the number of entries removed */ int priqueue_remove(priqueue_t *q, void *ptr) { int number_removed = 0; while(q->size >0 && ptr == get_obj_node(q->head)) { priqueue_poll(q); number_removed ++; } node_t *iterator, *node_ptr; if(q->size > 0) { iterator = q->head; while(iterator->next != NULL ) { if(get_obj_node(iterator->next) == ptr) { node_ptr = iterator -> next; iterator -> next = node_ptr -> next; q->size --; destroy_node(node_ptr); number_removed ++; continue; } iterator = iterator -> next; } } return number_removed; }
/** Free any memory associated with your scheduler. Assumptions: - This function will be the last function called in your library. */ void scheduler_clean_up() { void* p = NULL; while( (p = priqueue_poll(jobs)) != NULL ) free_job((job_t*)p); priqueue_destroy(jobs); free(jobs); free_core(&cores); }//scheduler_clean_up
/** When the scheme is set to RR, called when the quantum timer has expired on a core. If any job should be scheduled to run on the core free'd up by the quantum expiration, return the job_number of the job that should be scheduled to run on core core_id. @param core_id the zero-based index of the core where the quantum has expired. @param time the current time of the simulator. @return job_number of the job that should be scheduled on core cord_id @return -1 if core should remain idle */ int scheduler_quantum_expired(int core_id, int time) { // Increment Time inc_time(time); // Process quantumn rollover delete_job(core_id,cores.jobs[core_id]->jid); // Schedule new job job_t* p = priqueue_poll(jobs); if ( p != NULL ) { insert_job(core_id,p); return p->jid; }//if return -1; }//scheduler_quantum_expired
/** Removes the specified index from the queue, moving later elements up a spot in the queue to fill the gap. @param q a pointer to an instance of the priqueue_t data structure @param index position of element to be removed @return the element removed from the queue @return NULL if the specified index does not exist */ void *priqueue_remove_at(priqueue_t *q, int index) { if(index < 0) { ERROROUT("index should be positive."); return NULL; } if(index >= q->size) return NULL; if(index == 0) return priqueue_poll(q); int i; node_t *iterator = q->head, *node_ptr; for(i=1; i<= index -1 ; ++i) iterator = iterator -> next; node_ptr = iterator -> next; iterator -> next = node_ptr -> next; q-> size --; return destroy_node(node_ptr); }
/** Called when a job has completed execution. The core_id, job_number and time parameters are provided for convenience. You may be able to calculate the values with your own data structure. If any job should be scheduled to run on the core free'd up by the finished job, return the job_number of the job that should be scheduled to run on core core_id. @param core_id the zero-based index of the core where the job was located. @param job_number a globally unique identification number of the job. @param time the current time of the simulator. @return job_number of the job that should be scheduled to run on core core_id @return -1 if core should remain idle. */ int scheduler_job_finished(int core_id, int job_number, int time) { // Increment Time inc_time(time); // Process job termination job_t* p = delete_job(core_id,job_number); priqueue_remove(jobs,p); inc_wait(cur_t - p->arr_t - p->run_t); inc_turn(cur_t - p->arr_t); free_job(p); // Schedule new job p = priqueue_poll(jobs); if ( p != NULL ) { insert_job(core_id,p); return p->jid; }//if return -1; }//scheduler_job_finished
/** When the scheme is set to RR, called when the quantum timer has expired on a core. If any job should be scheduled to run on the core free'd up by the quantum expiration, return the job_number of the job that should be scheduled to run on core core_id. @param core_id the zero-based index of the core where the quantum has expired. @param time the current time of the simulator. @return job_number of the job that should be scheduled on core cord_id @return -1 if core should remain idle */ int scheduler_quantum_expired(int core_id, int time) { priqueue_offer(&job_queue, core_arr[core_id].core_job); core_arr[core_id].core_job = priqueue_poll(&job_queue); if (core_arr[core_id].core_job != NULL) { if (core_arr[core_id].core_job->first_runtime == -1) { core_arr[core_id].core_job->first_runtime = time; } core_arr[core_id].core_job->last_runtime = time; return core_arr[core_id].core_job->job_number; } return -1; }
/** Called when a job has completed execution. The core_id, job_number and time parameters are provided for convenience. You may be able to calculate the values with your own data structure. If any job should be scheduled to run on the core free'd up by the finished job, return the job_number of the job that should be scheduled to run on core core_id. @param core_id the zero-based index of the core where the job was located. @param job_number a globally unique identification number of the job. @param time the current time of the simulator. @return job_number of the job that should be scheduled to run on core core_id @return -1 if core should remain idle. */ int scheduler_job_finished(int core_id, int job_number, int time) { core_arr[core_id].core_job->waiting_time = (time - core_arr[core_id].core_job->arrival_time) - core_arr[core_id].core_job->running_time; core_arr[core_id].core_job->response_time = core_arr[core_id].core_job->first_runtime - core_arr[core_id].core_job->arrival_time; core_arr[core_id].core_job->turnaround_time = time - core_arr[core_id].core_job->arrival_time; priqueue_offer(&finished, core_arr[core_id].core_job); core_arr[core_id].core_job = priqueue_poll(&job_queue); if (core_arr[core_id].core_job != NULL) { if ( core_arr[core_id].core_job->first_runtime == -1) { core_arr[core_id].core_job->first_runtime = time; } core_arr[core_id].core_job->last_runtime = time; return core_arr[core_id].core_job->job_number; } return -1; }
int main() { priqueue_t q, q2; priqueue_init(&q, compare1); priqueue_init(&q2, compare2); /* Pupulate some data... */ int *values = malloc(100 * sizeof(int)); int i; for (i = 0; i < 100; i++) values[i] = i; /* Add 5 values, 3 unique. */ priqueue_offer(&q, &values[12]); priqueue_offer(&q, &values[13]); priqueue_offer(&q, &values[14]); priqueue_offer(&q, &values[12]); priqueue_offer(&q, &values[12]); printf("Total elements: %d (expected 5).\n", priqueue_size(&q)); priqueue_print(&q); int val_removed = *((int *)priqueue_remove_at(&q, 4)); printf("Element removed: %d (expected 14).\n", val_removed); printf("Total elements: %d (expected 4).\n", priqueue_size(&q)); int val = *((int *)priqueue_poll(&q)); printf("Top element: %d (expected 12).\n", val); printf("Total elements: %d (expected 3).\n", priqueue_size(&q)); int vals_removed = priqueue_remove(&q, &values[12]); printf("Elements removed: %d (expected 2).\n", vals_removed); printf("Total elements: %d (expected 1).\n", priqueue_size(&q)); priqueue_print(&q); priqueue_offer(&q, &values[10]); priqueue_offer(&q, &values[30]); priqueue_offer(&q, &values[20]); printf("Total elements: %d (expected 4).\n", priqueue_size(&q)); priqueue_offer(&q2, &values[10]); priqueue_offer(&q2, &values[30]); priqueue_offer(&q2, &values[20]); printf("Total elements: %d (expected 3).\n", priqueue_size(&q2)); printf("Elements in order queue (expected 10 13 20 30): "); for (i = 0; i < priqueue_size(&q); i++) printf("%d ", *((int *)priqueue_at(&q, i)) ); printf("\n"); printf("Elements in reverse order queue (expected 30 20 10): "); for (i = 0; i < priqueue_size(&q2); i++) printf("%d ", *((int *)priqueue_at(&q2, i)) ); printf("\n"); priqueue_destroy(&q2); priqueue_destroy(&q); printf("Total elements q: %d (expected 0).\n", priqueue_size(&q)); printf("Total elements q2: %d (expected 0).\n", priqueue_size(&q2)); free(values); return 0; }
/** Destroys and frees all the memory associated with q. @param q a pointer to an instance of the priqueue_t data structure */ void priqueue_destroy(priqueue_t *q) { while(q->head!=NULL) priqueue_poll(q); }
/** Destroys and frees all the memory associated with q. @param q a pointer to an instance of the priqueue_t data structure */ void priqueue_destroy(priqueue_t *q) { while(q->size >0) priqueue_poll(q); }
int main() { priqueue_t q, q2; priqueue_init(&q, compare1); priqueue_init(&q2, compare2); /* Pupulate some data... */ int *values = malloc(100 * sizeof(int)); int i; for (i = 0; i < 100; i++) values[i] = i; /* Add 5 values, 3 unique. */ priqueue_offer(&q, &values[12]); priqueue_offer(&q, &values[13]); priqueue_offer(&q, &values[14]); priqueue_offer(&q, &values[12]); priqueue_offer(&q, &values[12]); //priqueue_offer(&q, &values[15]); printf("Total elements: %d (expected 5).\n", priqueue_size(&q)); int val = *((int *)priqueue_poll(&q)); printf("Top element: %d (expected 12).\n", val); printf("Total elements: %d (expected 4).\n", priqueue_size(&q)); int val2 = *((int *)priqueue_poll(&q)); printf("Top element: %d (expected 12).\n", val2); printf("Total elements: %d (expected 3).\n", priqueue_size(&q)); int val3 = *((int *)priqueue_poll(&q)); printf("Top element: %d (expected 12).\n", val3); printf("Total elements: %d (expected 2).\n", priqueue_size(&q)); priqueue_offer(&q, &values[10]); priqueue_offer(&q, &values[30]); priqueue_offer(&q, &values[20]); /* priqueue_offer(&q, &values[15]); priqueue_offer(&q, &values[23]); priqueue_offer(&q, &values[31]); */priqueue_offer(&q2, &values[10]); priqueue_offer(&q2, &values[30]); priqueue_offer(&q2, &values[20]); printf("Elements in order queue (expected 10 13 14 20 30): "); while ( priqueue_size(&q) ) printf("%d ", *((int *)priqueue_poll(&q)) ); printf("\n"); printf("Elements in order queue (expected 30 20 10): "); while ( priqueue_size(&q2) ) printf("%d ", *((int *)priqueue_poll(&q2)) ); printf("\n"); priqueue_destroy(&q2); priqueue_destroy(&q); free(values); return 0; }