//===================================================== file = ibp_csim.c =====
//=  A CSIM18 simulation of an IBP/D/1 queueing system                        =
//=============================================================================
//=  Notes: Note that queueing will never occur due to max arrival rate       =
//=         is same as service rate (1 cell per slot).                        =
//=---------------------------------------------------------------------------=
//=  History:   KJC (06/30/00) - Genesis (from mm1_csim.c)                    =
//=============================================================================

//----- Includes --------------------------------------------------------------
#include <stdio.h>       // Needed for printf()
#include <math.h>        // Needed for pow()
#include "csim.h"        // Needed for CSIM18 stuff

//----- Defines ---------------------------------------------------------------
#define FALSE         0  // Boolean false
#define TRUE          1  // Boolean true
#define CELL_TIME   1.0  // Cell service time
#define SIM_TIME  1.0e6  // Total simulation time in cell times

//----- Globals ---------------------------------------------------------------
FACILITY Server;         // Pointer for Server facility
double   P;              // Pr[on at t+1 | on at t]
double   Q;              // Pr[off at t+1 | off at t]
double   Alpha;          // Pr[arrival at t | on]

//----- Prototypes ------------------------------------------------------------
void generate(void);     // Generate IBP customers
void queue1(void);       // Single server queue with deterministic service

//=============================================================================
//==  Main program                                                           ==
//=============================================================================
void sim(void)
{
  double   rho;          // Theoretical utilization
  double   cov;          // Theoretical CoV

  // Create the simulation
  create("sim");

  // Initializations
  Server = facility("Server");
  P = 0.30;
  Q = 0.40;
  Alpha = 0.90;

  // Output begin-of-simulation banner
  printf("*** BEGIN SIMULATION *** \n");

  // Initiate generate function and hold for SIM_TIME
  generate();
  hold(SIM_TIME);

  // Compute theoretical utilization and CoV
  rho = Alpha * (1.0 - Q) / (2.0 - P - Q);
  cov = 1.0 + Alpha * (((1.0 - P) * (P + Q)) / pow((2.0 - P - Q), 2.0) - 1.0);

  // Output results
  printf("============================================================= \n");
  printf("==    *** CSIM18 IBP/D/1 queueing system simulation ***    == \n");
  printf("============================================================= \n");
  printf("= P                  = %6.3f            \n", P);
  printf("= Q                  = %6.3f            \n", Q);
  printf("= Alpha              = %6.3f            \n", Alpha);
  printf("=------------------------------------------------------------ \n");
  printf("= Utilization        = %6.3f %%         \n", 100.0 * rho);
  printf("= CoV (C**2)         = %6.3f            \n", cov);
  printf("= Mean 'on' time     = %6.3f cell times \n", 1.0 / (1.0 - P));
  printf("= Mean 'off' time    = %6.3f cell times \n", 1.0 / (1.0 - Q));
  printf("=------------------------------------------------------------ \n");
  printf("= >>> Simulation results                                    - \n");
  printf("=------------------------------------------------------------ \n");
  printf("= Total CPU time     = %6.3f sec        \n", cputime());
  printf("= Total sim time     = %6.3f cell times \n", clock);
  printf("= Total completions  = %ld cells        \n", completions(Server));
  printf("= Utilization        = %6.3f %%         \n", 100.0 * util(Server));
  printf("= Mean num in system = %6.3f cells      \n", qlen(Server));
  printf("= Mean response time = %6.3f cell times \n", resp(Server));
  printf("= Mean service time  = %6.3f cell times \n", serv(Server));
  printf("= Mean throughput    = %6.3f cell/sec   \n", tput(Server));
  printf("============================================================= \n");

  // Output end-of-simulation banner
  printf("*** END SIMULATION *** \n");
}

//=============================================================================
//=  Traffic generator for IBP                                                =
//=============================================================================
void generate(void)
{
  double z;              // Uniform RV from 0.0 to 1.0
  int    on_flag;        // Flag for on or off

  create("generate");

  // Do forever (starting in an "on" period)
  on_flag = TRUE;
  while(TRUE)
  {
    // Loop for "on" case
    while (on_flag == TRUE)
    {
      z = uniform(0.0, 1.0);
      if (z <= Alpha) queue1();
      hold(CELL_TIME);

      z = uniform(0.0, 1.0);
      if (z > P) on_flag = FALSE;
    }

    // Loop for "off" case
    while (on_flag == FALSE)
    {
      hold(CELL_TIME);
      z = uniform(0.0, 1.0);
      if (z > Q) on_flag = TRUE;
    }
  }
}

//=============================================================================
//==  Function for single server queue with deteministic service time        ==
//=============================================================================
void queue1(void)
{
  create("queue1");

  // Reserve, hold for a cell time, and release server
  reserve(Server);
  hold(CELL_TIME);
  release(Server);
}

