예제 #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
/**
	Called when a new job arrives.
 
	If multiple cores are idle, the job should be assigned to the core with the
	lowest id.
	If the job arriving should be scheduled to run during the next
	time cycle, return the zero-based index of the core the job should be
	scheduled on. If another job is already running on the core specified,
	this will preempt the currently running job.
	Assumptions:
		- You may assume that every job wil have a unique arrival time.
	@param job_number a globally unique identification number of the job arriving.
	@param time the current time of the simulator.
	@param running_time the total number of time units this job will run before it will be finished.
	@param priority the priority of the job. (The lower the value, the higher the priority.)
	@return index of core job should be scheduled on
	@return -1 if no scheduling changes should be made. 
 
 */
int scheduler_new_job(int job_number, int time, int running_time, int priority)
{
	int i;
	inc_time(time);
	job_t* job = create_job(job_number, time, running_time, priority);

	if ( (i = get_core()) != -1 )
	{
		insert_job(i,job);
		return i;
	}//if
	else if ( is_prempt() )
	{
		i = preempt(job);
		if ( i == -1 )
			priqueue_offer(jobs,job);
		return i;
	}//else if
	priqueue_offer(jobs,job);
	return -1;
}//scheduler_new_job
예제 #3
0
job_t* delete_job(int core, int id)
{
	if ( cores.jobs[core]->jid != id )
	{
		printf("Delete job failed, invaild job ID");
		exit(1);
	}//if - attempt to remove invalid job from core

	job_t* job = cores.jobs[core];
	job->updt_core_t = -1;
	cores.jobs[core] = NULL;
	priqueue_offer(jobs,job);
	return job;
}//delete_job
예제 #4
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)
{
	
	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;

}
예제 #5
0
/**
  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;



				
			
}
예제 #6
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;
}
예제 #7
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

}
예제 #8
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]);
        //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;
}
예제 #9
0
/**
  Called when a new job arrives.
 
  If multiple cores are idle, the job should be assigned to the core with the
  lowest id.
  If the job arriving should be scheduled to run during the next
  time cycle, return the zero-based index of the core the job should be
  scheduled on. If another job is already running on the core specified,
  this will preempt the currently running job.
  Assumptions:
    - You may assume that every job wil have a unique arrival time.

  @param job_number a globally unique identification number of the job arriving.
  @param time the current time of the simulator.
  @param running_time the total number of time units this job will run before it will be finished.
  @param priority the priority of the job. (The lower the value, the higher the priority.)
  @return index of core job should be scheduled on
  @return -1 if no scheduling changes should be made. 
 
 */
int scheduler_new_job(int job_number, int time, int running_time, int priority)
{

	job_t * new_job = malloc(sizeof(job_t));
	
	
	new_job->job_number = job_number;
	new_job->priority = priority;
	new_job->remaining_time = running_time;
	new_job->running_time = running_time;


	new_job->arrival_time = time;
	new_job->first_runtime = -1;
	new_job->last_runtime = -1;
	
	job_count++;
	
	job_t *worst = NULL;
	int worst_index = -1;

	
	int i;

	for (i = 0; i < num_cores; i++) {

		if (core_arr[i].core_job != NULL) {
			
			core_arr[i].core_job->remaining_time = core_arr[i].core_job->remaining_time - (time - core_arr[i].core_job->last_runtime);
			core_arr[i].core_job->last_runtime = time;

		}

	}

	
	for (i = 0; i < num_cores; i++) {
	
		if (core_arr[i].core_job == NULL) {
			new_job->first_runtime = time;
			new_job->last_runtime = time;
			core_arr[i].core_job = new_job;
			return i;
		}

	}

	if (the_scheme == FCFS || the_scheme == SJF || the_scheme == PRI) {
			
		priqueue_offer(&job_queue, new_job);
		return -1;	

	}

	if (the_scheme == RR) {
		
		priqueue_offer(&job_queue, new_job);
		return -1;

	}
	
	if (the_scheme == PSJF || the_scheme == PPRI) {
		
		for (i = 0; i < num_cores; i++) {
			
			if (worst != NULL && job_queue.comp(worst, core_arr[i].core_job) < 0) {
									
				worst = core_arr[i].core_job;
				worst_index = i;
			}

			if (worst == NULL && job_queue.comp(new_job, core_arr[i].core_job) < 0) {

				worst = core_arr[i].core_job;
				worst_index = i;
			}

		}
		

		if (worst != NULL) {
			
			if (worst->first_runtime == time) {
				worst->first_runtime = -1;
			}

			if (worst->last_runtime == time) {
				worst->last_runtime = -1;
			}
			
			
			new_job->first_runtime = time;
			new_job->last_runtime = time;	
			core_arr[worst_index].core_job = new_job;
			priqueue_offer(&job_queue, worst);
			return worst_index;

		}
		
		if (worst == NULL) {

			priqueue_offer(&job_queue, new_job);
			return -1;		

		}


	}



	return -1;

}