Signals in OMNeT++
András Varga
OMNeT++ WorkshopMarch 19, 2010Malaga, Spain
Motivation
Problems to solve:
• Need more flexible statistics recording
• Ideally, module should just produce the values, and we want to be able to decide per-run basis what to record and how (vector, mean/stddev, histogram, etc.)
• Existing models: they need to calculate and output “everything”, and actual recording may be disabled via configuration options
• Support for global statistics processing modules
• Example: watch for the total #drops in the network to raise over a limit, and tune model parameters accordingly
• Currently not possible without changing participating modules
2
Motivation / 2
In the INET Framework:
• Support for exposing pcap traces
• We need to be able to record packet traces easily, without obtrusive changes to existing models:
• without inserting an extra submodule deep inside StandardHost
• without adding fwrite() calls and “string pcapFileName” parameters into L2 modules
• Support for creating global log files
• E.g. “nam” traces, whose contents should come from all over the simulation
• Model change notification
• Certain model components need to get informed about runtime topology changes
• For example, the PPP module needs to update internal cached channel pointer when it gets reconnected
3
Idea
Recurrent element:
• Producer of information needs to be decoupled from consumer.
4
Why not build a publish-subscribemechanism into OMNeT++ itself?
Note: there is MF’s Blackboard and INET’s NotificationBoard, but they are not suitable for many of these tasks (e.g. statistics, model change notification)
The Signals API
Component (module or channel) class:
• emit(signal, long)• emit(signal, double)• emit(signal, simtime_t)• emit(signal, const char *)• emit(signal, cObject *) for everything else
Listener (cIListener class):
• receiveSignal(sourceComponent, signal, long)• receiveSignal(sourceComponent, signal, double)• receiveSignal(sourceComponent, signal, simtime_t)• receiveSignal(sourceComponent, signal, const char *)• receiveSignal(sourceComponent, signal, cObject *)• +1: finish(component, signal) mostly for result recording
5
Adding Listeners
Component (module or channel) class:
• subscribe(signal, cIListener *)• unsubscribe(signal, cIListener *)• hasListeners(signal)
Listener (cIListener):
• subscribedTo(component, signal)• unsubscribedFrom(component, signal)
6
Signal Propagation
Signals propagate up the module tree:
– You can subscribe at the module, or at any ancestor
– Listeners subscribed at the root are catch-alls
– Optimization: no listener – no notification overhead!
Practical examples:
– INET’s NotificationBoard can be substituted by adding listeners to the host compound module
– Facilitates collecting global or aggregated statistics
• if statistics are exposed as signals, aggregation can be done by adding listeners at the root module
7
Identifying Signals
• Signals are identified by name (a string)
• During simulation: simsignal_t
– dynamically assigned numeric identifier, used for efficiency reasons; “signal ID”
– Obtaining the signal ID from signal name:
cComponent::registerSignal(“signalname”);
• Signal names and signal IDs are global
– Different modules “registering” (looking up) the same name get the same signal ID
8
NotificationBoard
Signals as replacement for INET’s NotificationBoard
• How?
– Modules emit notifications as (local) signals
– Listeners subscribe at the host/router compound module
• Why?
– Efficiency: signal allow emitting only when needed
• Notification information may be costly to produce, and maybe no one is listening! Signals have an efficient hasListeners() method.
– Uniformity:
• Signals emitted this way may be used for other purposes as well, e.g. for statistics recording (e.g. “number of routing table changes during simulation”)
9
Signals
Currently signals are ready to be used for:
• Model change notifications
• Statistics recording
• Model-specific use (e.g. as NotificationBoard)
Planned:
• pcap trace recording, nam trace recording
• As input for custom animations
• To be used by a future animation framework. Examples: wireless transmission effects; visualize routes discovered by routing protocols
10
Model Change Notifications
• Two predefined signals:
– PRE_MODEL_CHANGE, POST_MODEL_CHANGE
• Notifications are emitted as objects
– subclassed from cModelChangeNotification
– contain the details about the change
11
Model Change Notifications
Notification details data classes:
12
cPreModuleAddNotificationcPreModuleDeleteNotificationcPreModuleReparentNotificationcPreGateAddNotificationcPreGateDeleteNotificationcPreGateVectorResizeNotificationcPreGateConnectNotificationcPreGateDisconnectNotificationcPrePathCreateNotificationcPrePathCutNotificationcPreParameterChangeNotificationcPreDisplayStringChangeNotification
cPostModuleAddNotificationcPostModuleDeleteNotificationcPostModuleReparentNotificationcPostGateAddNotificationcPostGateDeleteNotificationcPostGateVectorResizeNotificationcPostGateConnectNotificationcPostGateDisconnectNotificationcPostPathCreateNotificationcPostPathCutNotificationcPostParameterChangeNotificationcPostDisplayStringChangeNotification
Model Change Notifications
Example notification details classes:class cPostGateVectorResizeNotification : ... { cModule *module; const char *gateName; int oldSize;};
class cPostGateConnectNotification : … { cGate *gate;};
class cPre/PostPathCreateNotification : … { same for xxxPathCutNotification
cGate *pathStartGate; cGate *pathEndGate; cGate *changedGate; the gate that got connected or
disconnected}; 13
Planned: Packet Trace Recording
Recording pcap traces:
– Modules emit packets as signal value (cPacket*)
– The simulation framework may subscribe to the signal
– Listener converts packets to byte arrays and records them into a pcap file
– Crucial: pcap-recording listener should be extensible
– Tkenv support (“Save pcap trace…” menu item)
14
Statistics Recording
Statistics recording using signals:
• Data are emitted as signals from modules/channels
– emit(signalID, x)
• Statistics are declared in the NED files
– @statistic property
– may define: name, title, interpolation mode, unit, default recording mode (as vector, as histogram, etc)
• Configurability:
– amount of information to be recorded can be changed from omnetpp.ini
• Compatibility:
– This is just a layer above existing vectors/scalars
15
Statistics
Basic syntax:
@statistic[name](attr1=value1;attr2=value2;…);
– Statistic name is also the signal name (by default)
– Attributes get recorded to the result files
– Some attribute names:
• title: text for chart legend
• unit: unit of measurement (for display on charts)
• interpolationmode: linear, sample-hold, backward-sample-hold, none (affects chart drawing)
16
Statistics: An Example
NED example:
simple Fifo { parameters: volatile double serviceTime @unit(s); @statistic[queueLen](title="queue length”;
interpolationmode=sample-hold); @statistic[busy](interpolationmode=sample-hold); @statistic[queueingTime](unit=s); gates: input in; output out;}
17
Statistics
• Recording mode:
– @statistic[qlen](record=vector,max,timeavg);
• Available recorders:
– last, mean, timeavg, min, max, sum, count, histogram, vector
– new ones can be defined
• Recording mode can be modified from omnetpp.ini:
– **.qlen.result-recoding-mode = +count,-vector
18
Statistics
When statistic name and signal name differ:
– @statistic[queueLength](source=qlen; record=vector,max,timeavg);
Object-to-number transformations:
– @statistic[numTxPks](source=“count(txStart)”; record=vector,last);
– @statistic[txBytes](source=“pkBytes(txStart)”; record=vector,histogram);
Expressions:
– @statistic[txBits](source=“8*pkBytes(txStart)”; record=vector,histogram);
– @statistic[txPksCum](source=“constant1(txStart)”;record=vector(sum));
19
Statistics
Recording with timestamp:
• Must be emitted as object (cObject*)
• Helper class: cTimestampedValue
– contains a timestamp and a value
• Usage:
cTimestampedValue tmp(timestamp, value);
emit(signalID, &tmp);
20
Statistics: Extensibility
Defining new result filters and result recorders
• To list existing ones:
$ ./mysim -h resultfilters
$ ./mysim -h resultrecorders
• To add existing ones:
• Implement ResultFilter / ResultRecorder (from src/envir)
• Register them with the Register_ResultFilter() and Register_ResultRecorder() macros
21
Statistics: Example Recorder class MeanRecorder : public NumericResultRecorder { protected: long count; double sum; protected: virtual void collect(double value) {count++; sum +=
value;} virtual void collect(simtime_t t, double value) {count++;
sum += value;} public: MeanRecorder() {count = 0; sum = 0;} virtual void finish(ResultFilter *prev) { opp_string_map attributes = getStatisticAttributes(); ev.recordScalar(getComponent(),
getResultName().c_str(), sum/count, &attributes); } }; Register_ResultRecorder(“mean”, MeanRecorder); 22
Conclusion
• A new Signals framework has been introduced in OMNeT++
• Purposes:
– Publish-subscribe communication in the model
– Statistics collection and recording
– Model change notification
– Trace file writing (pcap, nam)
– Other
23
Signals
Questions, comments?
Discussion
24