Exemplo n.º 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;
}
Exemplo n.º 2
0
/**
  This function may print out any debugging information you choose. This
  function will be called by the simulator after every call the simulator
  makes to your scheduler.
  In our provided output, we have implemented this function to list the jobs in the order they are to be scheduled. Furthermore, we have also listed the current state of the job (either running on a given core or idle). For example, if we have a non-preemptive algorithm and job(id=4) has began running, job(id=2) arrives with a higher priority, and job(id=1) arrives with a lower priority, the output in our sample output will be:

    2(-1) 4(0) 1(-1)  
  
  This function is not required and will not be graded. You may leave it
  blank if you do not find it useful.
 */
void scheduler_show_queue()
{
	int i;
	for(i=0; i<priqueue_size(ugh->thing); i++)
		printf("%d(%d) ", ( (job_t *) priqueue_at(ugh->thing, i))->job_number, ( (job_t *) priqueue_at(ugh->thing, i))->core);

	printf("\n");
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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

}