//====================================================== file = tr_smpl.c =====
//=  An SMPL simulation of a trace/trace/1 queue                              =
//=============================================================================
//=  Notes: 1) Assumes an input file with <delta_time, job_size> pairs with   =
//=            delta_time in real seconds and pkt_len in integer bytes        =
//=         2) Assumes Bottle_neck rate is in bits per second                 =
//=---------------------------------------------------------------------------=
//=  Build: bcc32 trtr1.c smpl.c bmeans.c rand.c                              =
//=---------------------------------------------------------------------------=
//=  Execute: tr_smpl bottleneck_rate < input_file > output_file              =
//=---------------------------------------------------------------------------=
//=  History:  KJC (03/12/01) - Genesis                                       =
//=============================================================================

//----- Include files ---------------------------------------------------------
#include "smpl.h"       // Needed for SMPL
#include <stdio.h>      // Needed for printf()
#include <stdlib.h>     // Needed for ato*() and exit()

//===== Main program ==========================================================
void main(int argc, char *argv[])
{
  double bottleneck_rate;  // Rate of bottleneck in bits/sec
  int    job_size;         // Job size in bytes
  double Ta;               // Interarrival time (sec)
  double Ts;               // Service time (sec)
  int    release_count;    // Release counter
  double thruput;          // Throughput in jobs/sec
  int    event;            // Event (1 = arrival, 2 = request, 3 = completion)
  int    server;           // Handle for server facility
  char   instring1[100];   // Input string #1
  char   instring2[100];   // Input string #2

  // Output usage
  if ((argc == 1) || (argv[1][0] == '?') || (argv[1][0] == '-'))
  {
    printf("-------------------------------------------- tr_smpl.c ----- \n");
    printf("- Usage: 'tr_smpl bottleneck_rate < input_file > output_file'\n");
    printf("-        where rate is the bottleneck rate (in bits/sec)     \n");
    printf("-        and input file is a file of tuples <delta_time,     \n");
    printf("-        job_size>.  Delta interarrival time is in seconds   \n");
    printf("-        and job size is in bytes.                           \n");
    printf("------------------------------------------------------------ \n");
    printf("- Contact: Ken Christensen (christen@csee.usf.edu)           \n");
    printf("-                          (813 974-4761 - office)           \n");
    printf("------------------------------------------------------------ \n");
    exit(1);
  }

  // Assign the bottleneck rate
  bottleneck_rate = atof(argv[1]);
  if (bottleneck_rate <= 0.0)
  {
    printf("*** ERROR - Bottleneck rate is invalid (rate = %f bits/sec) \n",
      bottleneck_rate);
    exit(1);
  }

  // Initialize variables
  release_count = 0;

  // Initialize SMPL subsystem and server facility
  smpl(0, "Trace/Trace/1 Queue");
  server=facility("server", 1);

  // Schedule arrival event at time 0 to kick-off simulation
  schedule(1, 0.0, job_size = 0);

  // Loop forever
  while (1)
  {
    // "Cause" the next event on the event list
    cause(&event,&job_size);

    // Process the event
    switch(event)
    {
      case 1:  // *** Arrival
        schedule(2, 0.0, job_size);
        scanf("%s %s \n", instring1, instring2);  // Read pair from stdin
        if (feof(stdin)) goto skip;               // If EOF we are done
        Ta = atof(instring1);                     // Resolve Ta
        job_size = atoi(instring2);               // Resolve job_size
        schedule(1, Ta, job_size);
        break;

      case 2:  // *** Request Server
        if (request(server, job_size, 0) == 0)
        {
          Ts = (8.0 * job_size) / bottleneck_rate;
          schedule(3, Ts, job_size);
        }
        break;

      case 3:  // *** Release server
        release(server, job_size);
        release_count++;
        break;
    }
  }

  // Bail-out to here
  skip:

  // Compute the throughput based on release count over total sim time
  thruput = release_count / time();

  // Output results
  printf("--------------------------------------------- tr_smpl.c ----- \n");
  printf("-  Utilization              = %6.3f %%    \n",
    100.0 * U(server));
  printf("-  Thruput                  = %f job/sec  \n",
    thruput);
  printf("-  Mean response time       = %f millisec \n",
    1000.0 * (Lq(server) + U(server)) / thruput);
  printf("-  Mean number in system    = %f jobs     \n",
    Lq(server) + U(server));
  printf("------------------------------------------------------------- \n");
}

