Main Page | Modules | Class Hierarchy | Class List | Directories | Class Members | Related Pages | Examples

Clock Class Reference

A clock allows us to compute time-based metrics by generating events at pre-set time intervals wrt the trace being generated. More...

#include <Clock.h>

List of all members.

Public Member Functions

 Clock (void)
 create a clock
 Clock (const Timeval &delta)
 create a clock that ticks at the given interval
 Clock (const Clock &toCopy)
Clockclone (const Clock &toCopy)
Clockoperator= (const Clock &rhs)
Alarm & addAlarm (AlarmListener &l, const Timeval &s, const Timeval &i)
 Add a repeating alarm initiated at a given time, occurring at a given interval.
void addAlarmEvent (Alarm &alarm, const Timeval &when)
 Method for Alarm objects to add AlarmEvents.
void updateClock (const Timeval &time)
 global clock update, called before a packet is processed
const TimevalgetTime (void) const
 get the current time
int getPhase (void) const
 get the current phase of the timeval

Static Public Member Functions

static ClockgetClock (void)

Static Public Attributes

static const int PHASE_PRETIME = 0
static const int PHASE_INTIME = 1
static const int PHASE_POSTTIME = 2

Protected Attributes

std::vector< Alarm * > alarms
std::priority_queue< AlarmEvent,
std::vector< AlarmEvent >,
std::greater< AlarmEvent > > 
Timeval currTime
int phase
bool started

Static Protected Attributes

static Clock theClock

Detailed Description

A clock allows us to compute time-based metrics by generating events at pre-set time intervals wrt the trace being generated.

Time is a major issue for this toolkit, in more ways than one. We wish to be able to support two types of time-driven attributes; those with a time-based window, and alarm-driven attributes. The former need to be able to update their windows appropriately, and the latter need to receive alarms at a pre-set interval in order to update. An example of windowed attributes is a buffer that maintains the packet length of every packet for a flow in the past 30 seconds; an example of an alarm-driven attribute is one that maintains a list of data volumes over discrete 30-second windows, and another example is one that computes the minimum 30-second data volume (over non-discrete intervals). This documentation discusses the motivation behind the time handling for the toolkit, as there are a number of very significant design decisions taken here based on many interacting factors - put simply, I think these things are VERY hazardous to muck with, so I'm trying to flag all the landmines.

Windowed attributes must be able to update their windows so that they contain all packets in a certain time window, without double-counting (unless it's a sliding window). That is, for a 30s window, the window starting at time 0s and the one starting at time 30s should not share any packets. They must also be able to ensure that their window is up-to-date at any given time.

Alarm-driven attributes must be able to tell the toolkit to poll them at a set frequency from a given start time, and the toolkit must ensure that these alarms are triggered. An alarm being triggered means a handler function being called in the attribute which set the alarm. It also must be able to ensure that an alarm set for the current time has gone off, due to the possibility of simultaneous alarms for multiple attributes with some interdependency (i.e. if A and B both have an alarm set for time t, and B depends on A, but B's alarm goes off first, then when A is queried by B, it has to be able to trigger its own alarm if appropriate).

To deal with the boundary problems that arise, we imagine three phases to each timeval: pretime, intime, and posttime. Pretime is an imaginary time before the timeval, and posttime an imaginary time after the timeval, wheras intime is the period of real time represented by the timeval. Pretime and posttime give us time to evalutate alarms when windows are in a consistent state. By this, we mean that in pretime for a timeval t, a window of time length w will include all packets in the interval [t-w,t), and in posttime for that timeval, it will include all packets in the interval (t-w,t]. During intime, no guarantees can be made, as we could be between processing two packets, both with a timestamp of t. Alarms for a specific timeval are handled in pretime for that timeval; the posttime is for a (to-be-implemented) `anytime' alarm functionality. That latter type of alarm is for min/max attributes that need to run computations before and after each timeval is handled. These phases spare us the metaphysical and pragmatic distresses inherent in `incrementing' a real valued timeval. :p

These mechanisms have consequences for purging flows with alarm-driven attributes; if a flow has a pending alarm, it should not be purged. For example, if a flow has a 30s data rate attribute, purging it while the alarm is still active would result in the packets between the end of the last full 30s segment and the end of the flow not being counted. Currently this is handled by leaving a flow in a `garbage bin' state and setting its alarms to go inactive after the next time they fire, then once all of the flow's alarms have gone inactive, it can be purged. >> On second thought, what we'll do for now is not leave the alarms on, but force alarm-driven attributes to have a `finalCalc' method that does whatever it has to to munge up the last value when the attribute is being deallocated.

Several design choices were made to accomodate all this messiness:

We can probably build a better system to handle time-based events. One option would be to implement multiple event channels, e.g. global, per flow, per attribute, etc., then have attributes subscribe to the appropriate channels. For example, a 'max datarate' attribute would have to subscribe to the appropriate packet length window, which would notify the former before and after any value was added or removed from the window. This route would require a lot of careful design to be sure that everything would work properly, without incurring excessive amounts of overhead.

make certain that all attributes update when their values are accessed, otherwise bad things _will_ happen. This would be best to do by changing the getAttrib handling so that the superclass was more involved, possibly by replacing the per-attribute function with an initialization that populates a member which could be accessed by Attribute::getAttrib.


Constructor & Destructor Documentation

Clock::Clock void   ) 

create a clock

Defaults to a 1s interval

Member Function Documentation

Alarm & Clock::addAlarm AlarmListener l,
const Timeval s,
const Timeval i

Add a repeating alarm initiated at a given time, occurring at a given interval.

s start time - not the first alarm, usually the time at which the alarm is set
i interval
l AlarmListener to be alerted
First alarm will be at time s + i; reason is that this will normally be used to specify "Send me an alarm in x seconds and every x seconds thereafter".

void Clock::addAlarmEvent Alarm &  alarm,
const Timeval when

Method for Alarm objects to add AlarmEvents.

alarm Alarm object registering alarm event
when time to set off alarm

void Clock::updateClock const Timeval time  ) 

global clock update, called before a packet is processed

time The time value of the packet about to be processed

The documentation for this class was generated from the following files:
Generated on Thu Apr 5 01:02:37 2007 for ANTARES by  doxygen 1.4.2