Пример #1
0
/**
  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)
{
/**
   * The current assumption is that this function works similarly for
   * every scheme. Preemption occurs when a new job arrives.
   */

  job_t *done; //the finished job
  job_t *next = NULL;
  
  //The core is now idle
  ugh->corelist[core_id] = 0;
  int index;
  for(index = 0; index < priqueue_size(ugh->thing); index++) 
    if( ((job_t *) priqueue_at(ugh->thing, index))->core == core_id) {
        done = (job_t *) priqueue_at(ugh->thing, index);
        break;
    }
            
  priqueue_remove_at(ugh->thing, index);
  
  //temporal statistics are calculated only when a job is done
 // ugh->total_response_time += done->response_time;
  ugh->total_turnaround_time += time - done->time;
 // ugh->total_waiting_time += done->waiting_time;

  done->when_preempted = time;
  done->is_running = 0;
  done->core = -1;
  done->running_time = done->running_time - time + done->start_time;

  done->time = time;

  priqueue_offer(ugh->thing, done);
            
  for(index = 0; index < priqueue_size(ugh->thing); index++)
    if( !((job_t *) priqueue_at(ugh->thing, index))->is_running) {
        next = (job_t *) priqueue_at(ugh->thing, index);
        break;
    }
          
    if(next) {
       next->core = core_id;
       ugh->corelist[core_id] = 1;
       next->is_running = 1;
       next->waiting_time += time - next->when_preempted;
       if(!next->firsty) {
            next->firsty = 1;
            next->first_time = time;
            next->response_time = time - next->time;
        }
        next->start_time = time;
        return next->job_number;
    }
   
    //The core should remain idle, such as for instance when the queue is empty.
    
    return -1;
}
Пример #2
0
/**
  Retrieves and removes the head of this queue, or NULL if this queue
  is empty.
 
  @param q a pointer to an instance of the priqueue_t data structure
  @return the head of this queue
  @return NULL if this queue is empty
 */
void *priqueue_poll(priqueue_t *q)
{
  if (q->head == NULL){
    return NULL;
  }
  return priqueue_remove_at(q,0);

	
}
Пример #3
0
/**
  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)
{
  struct node *tmp = q->head;
  int i = 0;
  int num = 0;
  while(tmp != NULL){
    if(tmp->data == ptr){
      tmp=tmp->next;
      priqueue_remove_at(q,i);
      num++;
    }else{
      i++;
      tmp=tmp->next;
    }

  }
  return num;
}
Пример #4
0
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;
}
Пример #5
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(priqueue_remove_at(q,0) != NULL){
  }
  //free(q);
}
Пример #6
0
int scheduler_new_job(int job_number, int time, int running_time, int priority)
{
  ugh->num_jobs++;

  job_t *job = (job_t *) malloc(sizeof(job_t));
  job->job_number = job_number;
  job->priority = priority;
  job->running_time = running_time;
  job->time = time; 
  job->start_time = -1;
  job->first_time = -1;
  job->is_running =
  job->firsty =
  job->response_time =
  job->waiting_time = 0;
  job->when_preempted = time;

  job->core = -1; //no core has been assigned to it yet

  priqueue_offer(ugh->thing, job); 

  //Look for an idle core
  int i;
  for(i=0; i<ugh->num_cores; i++)
    if(!ugh->corelist[i]) {
      ugh->corelist[i] = 1; //The core is now in use
      job->is_running = 1; //is being performed
      job->firsty = 1;
      job->start_time = time;
      job->first_time = time;
      job->response_time = 0;//time - job->time + 1;
      return job->core = i; //The id of the core to which job has been assigned.
    }

    if(ugh->sch/3 + ugh->sch%3 < 2 || ugh->sch == RR) return -1; //returns if nonpreemptive or RR
  
	/**
     * If there be no idle cores, use the power of preemption.
     * (Nonpreemptive jobs return -1 at the end of this function.)
     */

    //rt = REMAINING time, not running time; pt = priority
    int index, rt, lrt = -1, thindex = -1, pt, mpt = -1;
    job_t *curr;

    /**
     * PREEMPTIVE SHORTEST JOB FIRST:
     * This will preempt the job that is running with the largest
     * remaining time, if that time be greteater than the running
     * time for this job. It will additionally reschedule the 
     * preempted job with updated running time.
     * 
     * One must remember that these schemes are like the nonpreemptive
     * ones insomuch as there be no conflicts with jobs that are running.
     */
    if(ugh->sch == PSJF) {
        /**
         * Finding the largest remaining time of a running job and the index of the job
         * to which it belongs.
         */
	    for(index = 0; index < priqueue_size(ugh->thing); index++)
            if( ((job_t *) priqueue_at(ugh->thing, index))->is_running) {
                curr = (job_t *) priqueue_at(ugh->thing, index);
			
				if(lrt < (rt = curr->running_time - time + curr->start_time)) {
                    lrt = rt;
                    thindex = index;
                }
		    }
    }
    /**
     * PREEMPTIVE PRIORITY THING:
     * Similar to PSJF, except the basis for preemption is priority.
     */
    else if(ugh->sch == PPRI) {
        /**
         * Finding the largest priority number or lowest priority of a running job 
         * and the index of the job to which it belongs.
         */
        for(index = 0; index < priqueue_size(ugh->thing); index++)
            if( ((job_t *) priqueue_at(ugh->thing, index))->is_running) {
                curr = (job_t *) priqueue_at(ugh->thing, index);
            
                if(mpt <= (pt = curr->priority)) {
                    lrt = curr->running_time - time + curr->start_time;
                    mpt = pt;
                    thindex = index;
                }
            }
    }
        

    /**
     * thindex is the index of the job with the largest remaining time/priority number
     * that is currently running. It is this job that the new job must
     * attempt to preempt.
     */

    curr = priqueue_at(ugh->thing, thindex);

    if( (ugh->sch == PSJF && job->running_time < lrt) ||
        (ugh->sch == PPRI && job->priority < mpt) ) {
        
        job->core = curr->core; //assign job to run on the preempted job's core
        priqueue_remove_at(ugh->thing, thindex); //remove curr from the queue in order to fix its stats
        curr->running_time = lrt; //change its running time to be the remaining time
        curr->is_running = 0; //remember that it is no longer running
        job->is_running = job->firsty = 1;
        job->response_time = 0; //time - job->time + 1;
        curr->core = -1; //it is not running on any cores
        curr->when_preempted = time;
        if(curr->first_time == time) {
            curr->start_time = -1;
            curr->firsty = 0;
        }
        job->start_time = time;
        priqueue_offer(ugh->thing, curr); //put it back into the priority queue
        return job->core; //return the core on which job is to be run
    }
    
    return -1; //job needs to wait in line like everyone else

}