/*
 * ProcessControlBlock.java (Stores the information about the Job)
 *
 * Written by : Nitin Motgi   (nmotgi@cs.ucf.edu)
 *
 * This file provides the data structure and mechanism to access contents
 * of job object created. It also contains information that can be used by
 * the scheduler and dispatcher to manage the set of jobs. The information
 * in this file is mainly used for context switching between jobs. Once 
 * the jobs are created, they will be assigned this data structure which
 * then keeps the state of the job all till it's death.
 *
 * Portions copyright (c) 2001 to School of Electrical Engineering and 
 * Computer science, UCF.
 *
 * Use and distribution of this source code are strictly governed by
 * terms and condition of the author.
 *
 * $Id : ProcessControlBlock.java,  v1.0 1/31/2001. $
 *
 * Revision History. 
 * 1. Created Basic Method,            $Id: v1.0.0      1/31/2001.
 * 2. Added Documentation,             $Id: v1.0.1      2/01/2001.
 * 3. Added Three controllers,         $Id: v2.0.0      2/01/2001. 
 *    (lCST,lEOT and Mode are the three main indicators that are
 *     to make this simulation run.)  
 * 4. Added Check for Arrival times,   $Id: v2.1.0      2/02/2001.
 * 5. Documentation Modified,          $Id: v2.1.1      2/02/2001. 
 * 6. Final Documentation Check        $Id: v2.1.1      2/03/2001. 
 * 7. Final Functionality Check        $Id: v2.2.1      2/03/2001. 
 *
*/

/* Start of Class.*/
public class ProcessControlBlock extends Object{

   /* Job Controlled by this PCB.*/
   public Job thisJob;                  /* This points to Job Class.*/
   public boolean bDispFlag;            /* For first delay and display
                                           of job commenced.*/
   private int nJobState;               /* State in which Job can be.*/

   private long lCurrentCPUTime;        /* Total CPU Bursts.*/ 
   private long lCurrentIOTime;         /* Total IO Bursts.*/
   private long lCurrentWaitTime;       /* Total Current WaitTime.*/

   private long lArrivalTime;           /* Arrival Time of the Job.*/
   private long lCST;                   /* Current Stamped Time.*/
   private long lEOT;                   /* Event Offset Time.*/
   private long lFirstWaitTime;         /* Wait time incured when the
                                           job moved from Ready to CPU
                                           first time.*/

   private long lCurrentExecTime;       /* Amount that still needs to be
                                           executed.*/
   
   public final int STATE_CPU   = 1;    /* Indicating Job is in CPU 
                                           Burst.*/
   public final int STATE_IO    = 2;    /* Job in I/O burst.*/
   public final int STATE_COMP  = 3;    /* Job in Completed State.*/
   public final int STATE_READY = 4;    /* Job waiting in the Queue.*/
   public final int STATE_ARRV  = 5;    /* Job Arrived into the System.*/

   /************************************************************************
    * Default constructor.
   */
   public ProcessControlBlock(){  
    PCBInit();
   }/* End of default constructor.*/

   /*************************************************************************
    * Intialise the PCB.
    */
    private void PCBInit(){
     lCurrentWaitTime= 0;
     lCurrentCPUTime = 0;
     lCurrentIOTime  = 0;

     lCST            = 0;
     lFirstWaitTime  = 0;
    
     nJobState       = STATE_ARRV;
    }/* End of PCBInit.*/


   /*************************************************************************
    * Creates a Job Object with specified Time, Priority and Job ID.
    */
   public ProcessControlBlock(int nJobID,long lExecTime,int nPriority,
                              long lArrivalTime){
    /* Create a New Job within the PCB and Manage the Job using PCB 
       information.*/
    thisJob = new Job();
    thisJob.nJobID    = nJobID; 
    thisJob.rExecTime = lExecTime;
    thisJob.nPriority = nPriority;
    lCurrentExecTime  = lExecTime;
    this.lArrivalTime = lArrivalTime;
    this.lEOT         = lArrivalTime;
    bDispFlag         = false;
    PCBInit();
   }/* End of ProcessControlBlock.*/

   /*************************************************************************
    * GET and SET function to retrieve and update Wait time of the Job.
    */
   public long GetWaitTime(){ 
    return lCurrentWaitTime;
   }/* End of GetJobWaitTime.*/

   public void SetWaitTime(long lNewWaitTime){
    lCurrentWaitTime += lNewWaitTime;    
   }/* End of SetWaitTime.*/
   

   /*************************************************************************
    * GET and SET function to retrieve and update the time left for
    * execution.
    */
   public long GetCurrentExecTime(){ 
    return lCurrentExecTime;
   }/* End of GetCurrentExecTime.*/

   public void SetCurrentExecTime(long lTime){
    if(lCurrentExecTime-lTime >= 0) lCurrentExecTime-=lTime;
    else lCurrentExecTime = 0;
   }/* End of SetCurrentExecTime.*/

   /*************************************************************************
    * GET and SET function to retrieve and set the state of the Job.
    */
    public int GetState(){
     return nJobState;
    }/* End of GetState.*/

    public void SetState(int nState){
     nJobState = nState;
    }/* End of SetState.*/

   /*************************************************************************
    * GET and SET Priority of the Job.
    */
   public int GetPriority()  {
    return thisJob.nPriority;
   }/* End of GetJobPriority.*/

   public void SetPriority(int nPriority){
    thisJob.nPriority = nPriority;
   }/* End of SetPriority.*/

   /*************************************************************************
    * GET and SET CST of the Job.
    */
   public long GetCST(){
    if(lEOT == -1) return lCST;
    return lCST+lEOT;
   }/* End of GetCST.*/

   public void SetCST(long lCST){
    this.lCST = lCST;    
   }/* End of SetCST.*/

   public void SetEOT(long lEOT){
    this.lEOT = lEOT;
   }

   /*************************************************************************
    * GET arrival times of the job.
    */
   public long GetArrivalTime(){
    return lArrivalTime;
   }/* End of GetArrivalTime.*/

   /*************************************************************************
    * GET and SET, updates the CPU Burst variable.
    */
   public void SetCPUBurst(long lCPUBurst){
    lCurrentCPUTime += lCPUBurst;
   }/* End of SetCPUBurst.*/

   public long GetCPUBurst(){
    return lCurrentCPUTime;
   }/* End of GetCPUBurst.*/

   /*************************************************************************
    * GET and SET, Updated the IO Burst Variable.
    */
   public void SetIOBurst(long lIOBurst){
    lCurrentIOTime += lIOBurst;
   }/* End of SetIOBurst.*/

   public long GetIOBurst(){
    return lCurrentIOTime;
   }/* End of GetIOBurst.*/

   /*************************************************************************
    * GET and SET, First Wait time of the Job
    */
   public void SetFirstWaitTime(long lWaitTime){
    lFirstWaitTime=lWaitTime;
   }/* End of SetIOBurst.*/

   public long GetFirstWaitTime(){
    return lFirstWaitTime;
   }/* End of GetIOBurst.*/

   /*************************************************************************
    * Get Total Execution time including wait time.
    */
    public long GetTotalExecTime(){
     return (lCurrentIOTime + lCurrentCPUTime+lCurrentWaitTime);
    }/* End of GetTotalExecTime.*/

}/* End of Job.*/
    

