//===================================================== file = smpl_ex4.c ===== //= Central server queueing network simulation model = //============================================================================= //= Notes: This program adapted from MacDougall model of Figure 2.1 = //= - Changed all constants to caps = //= - Added and cleaned-up comments = //= - Expanded multi-instruction lines = //=---------------------------------------------------------------------------= //= Build: Standard SMPL build = //=---------------------------------------------------------------------------= //= History: KJC (02/17/05) - Genesis = //============================================================================= //----- Include files --------------------------------------------------------- #include // Needed for printf() #include "smpl.h" // Needed for SMPL //----- Constants ------------------------------------------------------------- #define N0 6 // Number of class 0 tasks #define N1 3 // Number of class 1 tasks #define NT (N0 + N1) // Total number of tasks #define ND 4 // Number of disk units #define QD 1 // Queued request return //----- External variables ---------------------------------------------------- struct token // Structure for a token (a "task") { int cls; // Task's class (and priority) int un; // Disk for current IO req. real ts; // Tour start time stamp } task[NT + 1]; int disk[ND + 1]; // Disk facility descriptors int cpu; // CPU facility descriptor int nts = 10000; // Number of tours to simulate real tc[2] = {10.0, 5.0}; // Class 0, 1 mean CPU times real td = 30.0; // Disk time mean real sd = 7.5; // Disk time standard deviation //===== Main program ========================================================== void main(void) { int i; // Task index int j; // Task class value int event; // Event number int n[2]; // Number of tours (for each class, 0 and 1) real t; // Time variable real s[2]; // Tour time (for each class, 0 and 1) struct token *p; // Pointer to a token (a task) // <#1> Intialize total number and time of tours to zero n[0] = n[1] = 0; s[0] = s[1] = 0.0; // <#2> Initialize class of each task (N0 of class 0, N1 of class1) for (i=1; i<=NT; i++) task[i].cls=(i > N0)? 1:0; // <#3> SMPL initializations smpl(0,"Central server model"); cpu=facility("CPU", 1); for (i=1; i<=ND; i++) disk[i] = facility("disk", 1); // <#4> Schedule begin of tours for all tasks for (i=1; i<=NT; i++) schedule(1, 0.0, i); // <#5> Main simulation loop while (nts) { // <#6> Cause an event and set p to point to task[i] cause(&event, &i); p = &task[i]; // <#7> Select appropriate event switch(event) { case 1: // ***** Begin tour p->ts = time(); // Task time stamp is current time schedule(2, 0.0, i); // Schedule CPU request now break; case 2: // ***** Request CPU j = p->cls; // Set j to task class if (preempt(cpu, i, j) != QD) // Preempt CPU if needed schedule(3, expntl(tc[j]), i); // to schedule CPU release break; case 3: // ***** Release CPU and select disk release(cpu, i); // Release the CPU for task i p->un = random(1, ND); // Choose a random disk unit schedule(4, 0.0, i); // Schedule disk request now break; case 4: // ***** Request disk if (request(disk[p->un], i, 0) != QD) // Queue on requested disk schedule(5, erlang(td, sd), i); // to schedule disk release break; case 5: // ***** Release disk and end tour release(disk[p->un], i); // Release the disk for task i j = p->cls; // Set j to class of task i t = time(); // Set t to current time s[j] = s[j] + (t - p->ts); // Update total tour time for class j p->ts = t; // Set task timestamp to current time n[j]++; // Incrment the tours for class i schedule(1, 0.0, i); // Schedule begin of tour now nts--; // Decrement the number of tours break; } } // <#8> Output SMPL report and class0, class1 tour times reportf(); printf("\n\n"); printf("class 0 tour time = %.2f\n", s[0] / n[0]); printf("class 1 tour time = %.2f\n", s[1] / n[1]); }