INET Framework for OMNeT++/OMNEST
inet::EagerGateScheduleConfigurator Class Reference

#include <EagerGateScheduleConfigurator.h>

Inheritance diagram for inet::EagerGateScheduleConfigurator:
inet::GateScheduleConfiguratorBase inet::NetworkConfiguratorBase

Classes

class  Slot
 

Protected Member Functions

virtual OutputcomputeGateScheduling (const Input &input) const override
 
virtual simtime_t computeStreamStartOffset (Input::Flow &flow, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
 
virtual simtime_t computeStartOffsetForPathFragments (Input::Flow &flow, std::string startNetworkNodeName, simtime_t startTime, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
 
virtual void addGateScheduling (Input::Flow &flow, int startIndex, int endIndex, simtime_t startOffset, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
 
virtual void addGateSchedulingForPathFragments (Input::Flow &flow, std::string startNetworkNodeName, simtime_t startTime, int index, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
 
- Protected Member Functions inherited from inet::GateScheduleConfiguratorBase
virtual void initialize (int stage) override
 
virtual void handleParameterChange (const char *name) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void clearConfiguration ()
 
virtual void computeConfiguration ()
 
virtual InputcreateGateSchedulingInput () const
 
virtual void addDevices (Input &input) const
 
virtual void addSwitches (Input &input) const
 
virtual void addPorts (Input &input) const
 
virtual void addFlows (Input &input) const
 
virtual void configureGateScheduling ()
 
virtual void configureGateScheduling (cModule *networkNode, cModule *gate, Interface *interface)
 
virtual void configureApplicationOffsets ()
 
- Protected Member Functions inherited from inet::NetworkConfiguratorBase
virtual ~NetworkConfiguratorBase ()
 
virtual int numInitStages () const override
 
virtual void extractTopology (Topology &topology)
 Extracts network topology by walking through the module hierarchy. More...
 
virtual std::vector< Node * > computeShortestNodePath (Node *source, Node *destination) const
 
virtual std::vector< Link * > computeShortestLinkPath (Node *source, Node *destination) const
 
virtual bool isBridgeNode (Node *node) const
 
virtual LinkfindLinkIn (const Node *node, const char *neighbor) const
 
virtual LinkfindLinkOut (const Node *node, const char *neighbor) const
 
virtual LinkfindLinkOut (const Node *node, const Node *neighbor) const
 
virtual LinkfindLinkOut (const Interface *interface) const
 
virtual Topology::LinkfindLinkOut (const Node *node, int gateId) const
 
virtual InterfacefindInterface (const Node *node, NetworkInterface *networkInterface) const
 

Additional Inherited Members

- Public Member Functions inherited from inet::GateScheduleConfiguratorBase
virtual ~GateScheduleConfiguratorBase ()
 
- Protected Attributes inherited from inet::GateScheduleConfiguratorBase
simtime_t gateCycleDuration
 
cValueArray * configuration = nullptr
 
InputgateSchedulingInput = nullptr
 
OutputgateSchedulingOutput = nullptr
 
- Protected Attributes inherited from inet::NetworkConfiguratorBase
Topologytopology = nullptr
 

Member Function Documentation

◆ addGateScheduling()

void inet::EagerGateScheduleConfigurator::addGateScheduling ( Input::Flow &  flow,
int  startIndex,
int  endIndex,
simtime_t  startOffset,
std::map< NetworkInterface *, std::vector< Slot >> &  interfaceSchedules 
) const
protectedvirtual
163 {
164  auto source = flow.startApplication->device->module;
165  auto destination = flow.endDevice->module;
166  auto pcp = flow.startApplication->pcp;
167  bps datarate = flow.startApplication->packetLength / s(flow.startApplication->packetInterval.dbl());
168  b packetLength = flow.startApplication->packetLength;
169  EV_DEBUG << "Allocating gate scheduling for stream reservation" << EV_FIELD(source) << EV_FIELD(destination) << EV_FIELD(pcp) << EV_FIELD(packetLength) << EV_FIELD(datarate) << EV_FIELD(gateCycleDuration, gateCycleDuration.ustr()) << EV_FIELD(startOffset, startOffset.ustr()) << EV_FIELD(startIndex) << EV_FIELD(endIndex) << EV_ENDL;
170  for (int index = startIndex; index < endIndex; index++) {
171  simtime_t startTime = startOffset + index * flow.startApplication->packetInterval;
172  addGateSchedulingForPathFragments(flow, source->getFullName(), startTime, index, interfaceSchedules);
173  }
174 }

Referenced by computeGateScheduling().

◆ addGateSchedulingForPathFragments()

void inet::EagerGateScheduleConfigurator::addGateSchedulingForPathFragments ( Input::Flow &  flow,
std::string  startNetworkNodeName,
simtime_t  startTime,
int  index,
std::map< NetworkInterface *, std::vector< Slot >> &  interfaceSchedules 
) const
protectedvirtual
177 {
178  auto destination = flow.endDevice->module;
179  auto pcp = flow.startApplication->pcp;
180  b packetLength = flow.startApplication->packetLength;
181  std::deque<std::tuple<std::string, simtime_t, std::vector<std::string>>> todos;
182  todos.push_back({startNetworkNodeName, startTime, {}});
183  while (!todos.empty()) {
184  auto todo = todos.front();
185  todos.pop_front();
186  for (auto pathFragment : flow.pathFragments) {
187  if (!strcmp(pathFragment->networkNodes.front()->module->getFullName(), std::get<0>(todo).c_str())) {
188  simtime_t nextGateOpenTime = std::get<1>(todo);
189  std::vector<std::string> extendedPath = std::get<2>(todo);
190  for (int i = 0; i < pathFragment->networkNodes.size() - 1; i++) {
191  auto networkNodeName = pathFragment->networkNodes[i]->module->getFullName();
192  extendedPath.push_back(networkNodeName);
193  auto networkNode = getParentModule()->getSubmodule(networkNodeName);
194  auto node = (Node *)topology->getNodeFor(networkNode);
195  auto link = (Link *)findLinkOut(node, pathFragment->networkNodes[i + 1]->module->getFullName());
196  auto interface = link->sourceInterface;
197  auto networkInterface = interface->networkInterface;
198  auto& interfaceSchedule = interfaceSchedules[networkInterface];
199  bps interfaceDatarate = bps(networkInterface->getDatarate());
200  simtime_t transmissionDuration = s(packetLength / interfaceDatarate).get();
201  simtime_t interFrameGap = s(b(96) / interfaceDatarate).get();
202  auto channel = dynamic_cast<cDatarateChannel *>(networkInterface->getTxTransmissionChannel());
203  simtime_t propagationDelay = channel != nullptr ? channel->getDelay() : 0;
204  simtime_t gateOpenDuration = transmissionDuration;
205  simtime_t gateOpenTime = nextGateOpenTime;
206  simtime_t gateCloseTime = gateOpenTime + gateOpenDuration;
207  for (int i = 0; i < interfaceSchedule.size(); i++) {
208  if (interfaceSchedule[i].gateCloseTime + interFrameGap <= gateOpenTime || gateCloseTime + interFrameGap <= interfaceSchedule[i].gateOpenTime)
209  continue;
210  else {
211  gateOpenTime = interfaceSchedule[i].gateCloseTime + interFrameGap;
212  gateCloseTime = gateOpenTime + gateOpenDuration;
213  i = 0;
214  }
215  }
216  simtime_t extraDelay = gateOpenTime - nextGateOpenTime;
217  EV_DEBUG << "Extending gate scheduling for stream reservation" << EV_FIELD(networkNode) << EV_FIELD(networkInterface) << EV_FIELD(pcp) << EV_FIELD(interfaceDatarate) << EV_FIELD(packetLength) << EV_FIELD(index) << EV_FIELD(startTime, startTime.ustr()) << EV_FIELD(gateOpenTime, gateOpenTime.ustr()) << EV_FIELD(gateCloseTime, gateCloseTime.ustr()) << EV_FIELD(gateOpenDuration, gateOpenDuration.ustr()) << EV_FIELD(extraDelay, extraDelay.ustr()) << EV_ENDL;
218  if (gateCloseTime > startTime + gateCycleDuration)
219  throw cRuntimeError("Gate scheduling doesn't fit into cycle duration");
220  Slot entry;
221  entry.gateOpenIndex = flow.gateIndex;
222  entry.gateOpenTime = gateOpenTime;
223  entry.gateCloseTime = gateCloseTime;
224  interfaceSchedule.push_back(entry);
225  nextGateOpenTime = gateCloseTime + propagationDelay;
226  }
227  auto endNetworkNodeName = pathFragment->networkNodes.back()->module->getFullName();
228  if (endNetworkNodeName == destination->getFullName() && nextGateOpenTime - startTime > flow.startApplication->maxLatency)
229  throw cRuntimeError("Cannot fit scheduling int maximum allowed latency");
230  if (endNetworkNodeName != destination->getFullName() && std::find(extendedPath.begin(), extendedPath.end(), endNetworkNodeName) == extendedPath.end())
231  todos.push_back({endNetworkNodeName, nextGateOpenTime, extendedPath});
232  }
233  }
234  }
235 }

◆ computeGateScheduling()

EagerGateScheduleConfigurator::Output * inet::EagerGateScheduleConfigurator::computeGateScheduling ( const Input input) const
overrideprotectedvirtual

Implements inet::GateScheduleConfiguratorBase.

25 {
26  std::map<NetworkInterface *, std::vector<Slot>> interfaceSchedules;
27  auto output = new Output();
28  for (auto flow : input.flows) {
29  simtime_t startOffset = computeStreamStartOffset(*flow, interfaceSchedules);
30  ASSERT(flow->startApplication->module);
31  output->applicationStartTimes[flow->startApplication] = startOffset;
32  addGateScheduling(*flow, 0, 1, startOffset, interfaceSchedules);
33  }
34  for (auto flow : input.flows) {
35  simtime_t startOffset = output->applicationStartTimes[flow->startApplication];
36  int count = gateCycleDuration / flow->startApplication->packetInterval;
37  if (gateCycleDuration != count * flow->startApplication->packetInterval)
38  throw cRuntimeError("Gate cycle duration must be a multiple of the application packet interval");
39  addGateScheduling(*flow, 1, count, startOffset, interfaceSchedules);
40  }
41  for (auto networkNode : input.networkNodes) {
42  for (auto port : networkNode->ports) {
43  auto& schedules = output->gateSchedules[port];
44  auto& slots = interfaceSchedules[check_and_cast<NetworkInterface *>(port->module)];
45  for (int gateIndex = 0; gateIndex < port->numGates; gateIndex++) {
46  auto schedule = new Output::Schedule();
47  schedule->port = port;
48  schedule->gateIndex = gateIndex;
49  schedule->cycleStart = 0;
50  schedule->cycleDuration = gateCycleDuration;
51  for (auto& slot : slots) {
52  if (slot.gateOpenIndex == gateIndex) {
53  simtime_t slotStart = slot.gateOpenTime;
54  simtime_t slotEnd = slot.gateCloseTime;
55  simtime_t slotDuration = slot.gateCloseTime - slot.gateOpenTime;
56  if (slotStart < gateCycleDuration && slotEnd > gateCycleDuration) {
57  Output::Slot scheduleSlot;
58  scheduleSlot.start = slotStart;
59  scheduleSlot.duration = gateCycleDuration - slotStart;
60  schedule->slots.push_back(scheduleSlot);
61  scheduleSlot.start = 0;
62  scheduleSlot.duration = slotDuration - scheduleSlot.duration;
63  schedule->slots.push_back(scheduleSlot);
64  }
65  else {
66  Output::Slot scheduleSlot;
67  scheduleSlot.start = simtimeModulo(slotStart, gateCycleDuration);
68  scheduleSlot.duration = slotDuration;
69  schedule->slots.push_back(scheduleSlot);
70  }
71  }
72  }
73  auto& slots = schedule->slots;
74  std::sort(slots.begin(), slots.end(), [] (const Output::Slot& slot1, const Output::Slot& slot2) {
75  return slot1.start < slot2.start;
76  });
77  schedules.push_back(schedule);
78  }
79  }
80  }
81  return output;
82 }

◆ computeStartOffsetForPathFragments()

simtime_t inet::EagerGateScheduleConfigurator::computeStartOffsetForPathFragments ( Input::Flow &  flow,
std::string  startNetworkNodeName,
simtime_t  startTime,
std::map< NetworkInterface *, std::vector< Slot >> &  interfaceSchedules 
) const
protectedvirtual
105 {
106  auto destination = flow.endDevice->module;
107  b packetLength = flow.startApplication->packetLength;
108  simtime_t result = 0;
109  std::deque<std::tuple<std::string, simtime_t, std::vector<std::string>>> todos;
110  todos.push_back({startNetworkNodeName, startTime, {}});
111  while (!todos.empty()) {
112  auto todo = todos.front();
113  todos.pop_front();
114  simtime_t startOffsetShift = 0;
115  for (auto pathFragment : flow.pathFragments) {
116  if (!strcmp(pathFragment->networkNodes.front()->module->getFullName(), std::get<0>(todo).c_str())) {
117  simtime_t nextGateOpenTime = std::get<1>(todo);
118  std::vector<std::string> extendedPath = std::get<2>(todo);
119  for (int i = 0; i < pathFragment->networkNodes.size() - 1; i++) {
120  auto networkNodeName = pathFragment->networkNodes[i]->module->getFullName();
121  extendedPath.push_back(networkNodeName);
122  auto networkNode = getParentModule()->getSubmodule(networkNodeName);
123  auto node = (Node *)topology->getNodeFor(networkNode);
124  auto link = (Link *)findLinkOut(node, pathFragment->networkNodes[i + 1]->module->getFullName());
125  auto interface = link->sourceInterface;
126  auto networkInterface = interface->networkInterface;
127  auto& interfaceSchedule = interfaceSchedules[networkInterface];
128  bps interfaceDatarate = bps(networkInterface->getDatarate());
129  simtime_t transmissionDuration = s(packetLength / interfaceDatarate).get();
130  simtime_t interFrameGap = s(b(96) / interfaceDatarate).get();
131  auto channel = dynamic_cast<cDatarateChannel *>(networkInterface->getTxTransmissionChannel());
132  simtime_t propagationDelay = channel != nullptr ? channel->getDelay() : 0;
133  simtime_t gateOpenDuration = transmissionDuration;
134  simtime_t gateOpenTime = nextGateOpenTime;
135  simtime_t gateCloseTime = gateOpenTime + gateOpenDuration;
136  for (int i = 0; i < interfaceSchedule.size(); i++) {
137  if (interfaceSchedule[i].gateCloseTime + interFrameGap <= gateOpenTime || gateCloseTime + interFrameGap <= interfaceSchedule[i].gateOpenTime)
138  continue;
139  else {
140  gateOpenTime = interfaceSchedule[i].gateCloseTime + interFrameGap;
141  gateCloseTime = gateOpenTime + gateOpenDuration;
142  i = 0;
143  }
144  }
145  simtime_t gateOpenDelay = gateOpenTime - nextGateOpenTime;
146  if (gateOpenDelay != 0) {
147  startOffsetShift += gateOpenDelay;
148  break;
149  }
150  nextGateOpenTime = gateCloseTime + propagationDelay;
151  }
152  auto endNetworkNodeName = pathFragment->networkNodes.back()->module->getFullName();
153  if (endNetworkNodeName != destination->getFullName() && std::find(extendedPath.begin(), extendedPath.end(), endNetworkNodeName) == extendedPath.end())
154  todos.push_back({endNetworkNodeName, nextGateOpenTime, extendedPath});
155  }
156  }
157  result += startOffsetShift;
158  }
159  return result;
160 };

Referenced by computeStreamStartOffset().

◆ computeStreamStartOffset()

simtime_t inet::EagerGateScheduleConfigurator::computeStreamStartOffset ( Input::Flow &  flow,
std::map< NetworkInterface *, std::vector< Slot >> &  interfaceSchedules 
) const
protectedvirtual
85 {
86  auto source = flow.startApplication->device->module;
87  auto destination = flow.endDevice->module;
88  auto pcp = flow.startApplication->pcp;
89  bps datarate = flow.startApplication->packetLength / s(flow.startApplication->packetInterval.dbl());
90  b packetLength = flow.startApplication->packetLength;
91  EV_DEBUG << "Computing start offset for stream reservation" << EV_FIELD(source) << EV_FIELD(destination) << EV_FIELD(pcp) << EV_FIELD(packetLength) << EV_FIELD(datarate) << EV_FIELD(gateCycleDuration, gateCycleDuration.ustr()) << EV_ENDL;
92  simtime_t startOffset = 0;
93  while (true) {
94  auto startOffsetShift = computeStartOffsetForPathFragments(flow, source->getFullName(), startOffset, interfaceSchedules);
95  if (startOffsetShift == 0)
96  break;
97  else
98  startOffset += startOffsetShift;
99  }
100  EV_DEBUG << "Setting start offset for stream reservation" << EV_FIELD(source) << EV_FIELD(destination) << EV_FIELD(pcp) << EV_FIELD(packetLength) << EV_FIELD(datarate) << EV_FIELD(gateCycleDuration, gateCycleDuration.ustr()) << EV_FIELD(startOffset, startOffset.ustr()) << EV_ENDL;
101  return startOffset;
102 }

Referenced by computeGateScheduling().


The documentation for this class was generated from the following files:
inet::EagerGateScheduleConfigurator::computeStartOffsetForPathFragments
virtual simtime_t computeStartOffsetForPathFragments(Input::Flow &flow, std::string startNetworkNodeName, simtime_t startTime, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
Definition: EagerGateScheduleConfigurator.cc:104
inet::NetworkConfiguratorBase::findLinkOut
virtual Link * findLinkOut(const Node *node, const char *neighbor) const
Definition: NetworkConfiguratorBase.cc:116
inet::sort
void sort(std::vector< T > &v)
Definition: stlutils.h:129
inet::units::units::bps
compose< b, pow< s, -1 > > bps
Definition: Units.h:1169
inet::count
int count(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:54
inet::Topology::getNodeFor
Node * getNodeFor(cModule *mod) const
Returns the graph node which corresponds to the given module in the network.
Definition: Topology.cc:355
inet::find
std::vector< T >::iterator find(std::vector< T > &v, const Tk &a)
Definition: stlutils.h:44
inet::units::values::s
value< double, units::s > s
Definition: Units.h:1235
EV_FIELD
#define EV_FIELD(...)
Definition: INETDefs.h:112
inet::GateScheduleConfiguratorBase::gateCycleDuration
simtime_t gateCycleDuration
Definition: GateScheduleConfiguratorBase.h:195
inet::EagerGateScheduleConfigurator::addGateScheduling
virtual void addGateScheduling(Input::Flow &flow, int startIndex, int endIndex, simtime_t startOffset, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
Definition: EagerGateScheduleConfigurator.cc:162
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::EagerGateScheduleConfigurator::addGateSchedulingForPathFragments
virtual void addGateSchedulingForPathFragments(Input::Flow &flow, std::string startNetworkNodeName, simtime_t startTime, int index, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
Definition: EagerGateScheduleConfigurator.cc:176
inet::simtimeModulo
simtime_t simtimeModulo(simtime_t a, simtime_t b)
Definition: EagerGateScheduleConfigurator.cc:19
inet::EagerGateScheduleConfigurator::computeStreamStartOffset
virtual simtime_t computeStreamStartOffset(Input::Flow &flow, std::map< NetworkInterface *, std::vector< Slot >> &interfaceSchedules) const
Definition: EagerGateScheduleConfigurator.cc:84
inet::NetworkConfiguratorBase::topology
Topology * topology
Definition: NetworkConfiguratorBase.h:67
EV_ENDL
#define EV_ENDL
Definition: INETDefs.h:114