/* Implements a first-come, first-served scheduler according to the
 * simulation interface
 * 
 * Created by Henry Walker, 27 September 2004
 * Revised by
 *   Janet Davis, 24 September 2006
 *   Jerod Weinman, 27 May 2008
 */

#include <stdlib.h>
#include "scheduler.h" /* defines functions for the scheduler interface */

/* variable declaration for active jobs currently available for execution */
struct jobQueue readyJobs;

/* returns true (1) if queue is empty and false (0) otherwise */
int jobQueueIsEmpty (void) 
{
     return (readyJobs.first == NULL);
}

/* initialize jobQueue to a null queue */
void initializeJobQueue (void)
{
     readyJobs.first = NULL;
     readyJobs.last  = NULL;
}

/* insert job into job queue */
void insertJob (struct Event * job) 
{
     struct jobQueueNode *newNode
          = (struct jobQueueNode *) malloc (sizeof(struct jobQueueNode));

     /* copy event data to newNode */
     newNode->job = job;

     /* insert node into queue list */
     newNode->next = NULL;

     if (readyJobs.first == NULL) 
     {
          readyJobs.first = newNode;
          readyJobs.last  = newNode;
     } 
     else 
     {
          readyJobs.last->next  = newNode;
          readyJobs.last  = newNode;
     }
}

/* remove job at head of queue and return it */
struct Event * selectJob (void) 
{
     struct Event * job;
     struct jobQueueNode *temp;

     /* if no jobs are ready, return NULL */
     if (readyJobs.first == NULL)
          return NULL;
  
     /* next job is at front of queue */
     job = readyJobs.first->job;
     
     /* record node at front of queue, so it can be removed later */
     temp = readyJobs.first;
     
     /* remove first job from queue */
     readyJobs.first = readyJobs.first->next;
     
     /* check if queue is now empty */
     if (readyJobs.first == NULL) 
     {
          readyJobs.last = NULL;
     }

     /* return old front of queue to memory pool */
     free(temp);

     return job;
}
