next up previous contents
Next: The resource class Up: Queuing events Previous: An M/M/1 Queue

Queue behavior

In this section we look at some examples of how more complex scenarios involving queues can be modeled.

Queue swapping

This behavior occurs when a member of the queue leaves in preference for an alternative queue. We can model the swapping of an event e between the queues q1 and q2 as follows :

   if (condition)
   {
     if (q1 -> extract(e))         // from every position
       q2 -> append(e);            // append to second queue
   }
where condition could be something as the checking of the sizes of the two queues.

Balking

If a queue is too long it usually deters further additions. This phenomenon is called balking and its implementation is straightforward :

   if (q -> size() < MAX)
     q -> append(e);                // append if possible

The event is appended when there is room for it.

Reneging

Reneging is the premature departure of a customer from a queue before it has had any service. This is typically the case when its waiting time exceeded some upper limit. We could model this by checking the entire queue with the queue::cancel method, but more efficient is the following addition to the arrival event :

  
   cancel* cn = new cancel(this);   // give customer to the cancel event
   sim -> schedule(cn,MAX);         // schedule cancel event
and the extracting of the event in the cancel::operator function. The queue::extract function does nothing if the event is not in the queue.
   int cancel::operator()()
   {
     if (q -> extract(e))         // extract and terminate e if in the queue
       sim -> terminate(e);
     return OK;
   }

Service pre-emption

Pre-emption occurs when a customer being served is interrupted by the server in favor of a new customer that has a higher priority. The interrupted customer can then wait to complete its service, wait to be served again or simply leave the system. The interrupting arrival then takes the place of the interrupted event. Consider the following behavior of the server entity of the M/M/1 queue. Events should then receive a queuing priority when created and the event currently being served should be set to NULL when terminated.

   int server::operator()()
   {
     if (!(q -> empty()))                // if an event waiting
       if (!current)                     // if nothing being served
         return serve();                 // just serve
       else if (q -> front() -> queuingpriority() > current -> queuingpriority())
         return preempt();               // front has a higher priority
   }
 
   int server::serve()
   {
     customer* c = (customer* )q -> removefront();
     r -> acquire();
     current = c;                          // record as current
     sim -> schedule(c,g -> exponential(meanservice));
     c -> phase(DEPARTURE);
     return OK;
   }
 
   int server::preempt()
   {
     sim -> passivate(current);            // extract departure
     r -> release();                       // and depart
     sim -> terminate(current);
 
     customer* c = (customer* )q -> removefront();
     r -> acquire();
     current = c;                          // record as current
     sim -> schedule(c,g -> exponential(meanservice));
     c -> phase(DEPARTURE);
     return OK;
   }

If the front can be served we look if there is currently a customer being served (the current variable is set to NULL in the departure event). If so the front is served only if its queuing priority is higher. The front is then recorded as the current.

Time dependencies

The arrival and service rates have been considered constant so far. This is not always realistic. The arrival rate at a supermarket shows a noticeable peak around evening for example. We can easily model this by constructing an arrivaltime function as follows :

 
   double arrivaltime()
   {
     double t = g -> exponential(MEAN1);
     if (sim -> clock() + t < TIME)        // use the appropriate mean
       return t;                           // based on the current
     else                                  // simulation time
       return (g -> exponential(MEAN2));
   }

and we have different arrival rates at different times, if this function is used when a new arrival is scheduled.



next up previous contents
Next: The resource class Up: Queuing events Previous: An M/M/1 Queue



A Eliens
Tue Oct 31 09:27:21 MET 1995