/*
 * shadowcpu.c
 *
 * Created by NJG: Fri May  3 18:41:04  2002
 *
 * Taken from p.254 of "Capacity Planning and Performance Modeling," 
 * by Menasce, Almeida, and Dowdy, Prentice-Hall, 1994. 
 * 
 */

#include 
#include 
#include "../lib/PDQ_Lib.h"

#define PRIORITY TRUE // Turn priority on or off here


main() {

   extern int      nodes, streams;

   char *noPri = "CPU Scheduler - No Pri";
   char *priOn = "CPU Scheduler - Pri On";
   float Ucpu_prod;
   float GetProdU();


   if (PRIORITY) { 
   	Ucpu_prod = GetProdU();
   }

   PDQ_Init(PRIORITY ? priOn : noPri);

   // workloads ...
   streams = PDQ_CreateClosed("Production", TERM, 20.0, 20.0);
   streams = PDQ_CreateClosed("Developmnt", TERM, 15.0, 15.0);

   // queueing nodes ...
   nodes = PDQ_CreateNode("CPU", CEN, FCFS);
   if (PRIORITY) { 
   	nodes = PDQ_CreateNode("shadCPU", CEN, FCFS);
   }
   nodes = PDQ_CreateNode("DK1", CEN, FCFS);
   nodes = PDQ_CreateNode("DK2", CEN, FCFS);

   // service demands at each node ...
   PDQ_SetDemand("CPU", "Production", 0.30);
   if (PRIORITY) { 
   	PDQ_SetDemand("shadCPU", "Developmnt", 1.00/(1 - Ucpu_prod));
   } 
   else { 
   	PDQ_SetDemand("CPU", "Developmnt", 1.00);
   }

   PDQ_SetDemand("DK1", "Production", 0.08);
   PDQ_SetDemand("DK1", "Developmnt", 0.05);

   PDQ_SetDemand("DK2", "Production", 0.10);
   PDQ_SetDemand("DK2", "Developmnt", 0.06);

   // We use APPROX rather than EXACT to match the numbers in the book
   PDQ_Solve(APPROX); 
   PDQ_Report();

}




float GetProdU() {

   extern int      nodes, streams;

   PDQ_Init("");

   streams = PDQ_CreateClosed("Production", TERM, 20.0, 20.0);
   nodes = PDQ_CreateNode("CPU", CEN, FCFS);
   nodes = PDQ_CreateNode("DK1", CEN, FCFS);
   nodes = PDQ_CreateNode("DK2", CEN, FCFS);

   PDQ_SetDemand("CPU", "Production", 0.30);
   PDQ_SetDemand("DK1", "Production", 0.08);
   PDQ_SetDemand("DK2", "Production", 0.10);

   PDQ_Solve(APPROX); 

   return(PDQ_GetUtilization("CPU", "Production", TERM));

}