From 80c9a230ca8035ab9c554cb9575f4e7d40445b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teresa=20L=C3=BCbeck?= Date: Tue, 7 May 2024 16:30:49 +0200 Subject: [PATCH] asynchronous traffic shaper with scheduler groups Version of EligibilityTimeMeter with shared eligibility times between streams of a group. Supported by GroupEligibilityTimeTable and a Ieee8021qFilter integrating the GroupEligibilityTimeTable with the GroupEligibilityTimeMeter. --- .../ieee8021q/ATSIeee8021qFilter.ned | 32 +++++++++ .../shaper/GroupEligibilityTimeMeter.cc | 68 +++++++++++++++++++ .../shaper/GroupEligibilityTimeMeter.h | 29 ++++++++ .../shaper/GroupEligibilityTimeMeter.ned | 24 +++++++ .../shaper/GroupEligibilityTimeTable.cc | 56 +++++++++++++++ .../shaper/GroupEligibilityTimeTable.h | 42 ++++++++++++ .../shaper/GroupEligibilityTimeTable.ned | 23 +++++++ 7 files changed, 274 insertions(+) create mode 100644 src/inet/linklayer/ieee8021q/ATSIeee8021qFilter.ned create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.cc create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.h create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.ned create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeTable.cc create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeTable.h create mode 100644 src/inet/protocolelement/shaper/GroupEligibilityTimeTable.ned diff --git a/src/inet/linklayer/ieee8021q/ATSIeee8021qFilter.ned b/src/inet/linklayer/ieee8021q/ATSIeee8021qFilter.ned new file mode 100644 index 00000000000..7feb409a405 --- /dev/null +++ b/src/inet/linklayer/ieee8021q/ATSIeee8021qFilter.ned @@ -0,0 +1,32 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +package inet.linklayer.ieee8021q; + +import inet.linklayer.ieee8021q.SimpleIeee8021qFilter; +import inet.protocolelement.shaper.GroupEligibilityTimeTable; + +// This module implements a filtering module for the asynchronous traffic shaper +// taking scheduler groups into account. +// +// This module is part of the asynchronous shaper infrastructure. +// +// @see ~EligibilityTimeGate, ~GroupEligibilityTimeMeter, ~EligibilityTimeFilter, ~EligibilityTimeQueue, ~EligibilityTimeTag +// +module ATSIeee8021qFilter extends SimpleIeee8021qFilter +{ + parameters: + + **.groupEligibilityTimeTableModule = default(absPath(".groupEligibilityTimeTable")); + + meter[*].typename = "GroupEligibilityTimeMeter"; + filter[*].typename = "EligibilityTimeFilter"; + + submodules: + groupEligibilityTimeTable: GroupEligibilityTimeTable { + @display("p=43,30"); + } +} diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.cc b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.cc new file mode 100644 index 00000000000..a679e32ec54 --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.cc @@ -0,0 +1,68 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#include "GroupEligibilityTimeMeter.h" + +#include "inet/common/DirectionTag_m.h" +#include "inet/linklayer/common/PcpTag_m.h" +#include "inet/protocolelement/shaper/EligibilityTimeTag_m.h" +#include "inet/linklayer/common/InterfaceTag_m.h" + +namespace inet { + +Define_Module(GroupEligibilityTimeMeter); + +void GroupEligibilityTimeMeter::initialize(int stage) +{ + EligibilityTimeMeter::initialize(stage); + if (stage == INITSTAGE_LOCAL) + { + groupEligibilityTimeTable.reference(this, "groupEligibilityTimeTableModule", true); + } +} + +void GroupEligibilityTimeMeter::meterPacket(Packet *packet) +{ + emitNumTokenChangedSignal(packet); + clocktime_t arrivalTime = getClockTime(); + clocktime_t lengthRecoveryDuration = s((packet->getDataLength() + packetOverheadLength) / committedInformationRate).get(); + clocktime_t emptyToFullDuration = s(committedBurstSize / committedInformationRate).get(); + clocktime_t schedulerEligibilityTime = bucketEmptyTime + lengthRecoveryDuration; + clocktime_t bucketFullTime = bucketEmptyTime + emptyToFullDuration; + clocktime_t eligibilityTime; + + //update groupEligibilityTime + auto packetDirection = packet->findTag(); + int pcp = 0; + if (packetDirection->getDirection() == DIRECTION_INBOUND) + { + auto pcpTag = packet->findTag(); + pcp = pcpTag->getPcp(); + } + else + { + auto pcpTag = packet->findTag(); + pcp = pcpTag->getPcp(); + } + auto iterface = packet->findTag(); + int port = iterface->getInterfaceId(); + std::string group = std::to_string(port) + "-" + std::to_string(pcp); + groupEligibilityTime = groupEligibilityTimeTable->getGroupEligibilityTime(group); + + eligibilityTime.setRaw(std::max(std::max(arrivalTime.raw(), groupEligibilityTime.raw()), schedulerEligibilityTime.raw())); + if (maxResidenceTime == -1 || eligibilityTime <= arrivalTime + maxResidenceTime) { + groupEligibilityTime = eligibilityTime; + // write groupEligibilityTime back into table + groupEligibilityTimeTable->updateGroupEligibilityTime(group, groupEligibilityTime); + + bucketEmptyTime = eligibilityTime < bucketFullTime ? schedulerEligibilityTime : schedulerEligibilityTime + eligibilityTime - bucketFullTime; + packet->addTagIfAbsent()->setEligibilityTime(eligibilityTime); + emitNumTokenChangedSignal(packet); + } + +} + +} //namespace inet diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.h b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.h new file mode 100644 index 00000000000..0eb891500b1 --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.h @@ -0,0 +1,29 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#ifndef INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMEMETER_H_ +#define INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMEMETER_H_ + +#include "inet/protocolelement/shaper/EligibilityTimeMeter.h" +#include "inet/common/ModuleRefByPar.h" +#include "GroupEligibilityTimeTable.h" + +namespace inet { + +class GroupEligibilityTimeMeter : public EligibilityTimeMeter +{ + protected: + ModuleRefByPar groupEligibilityTimeTable; + + protected: + virtual void initialize(int stage) override; + virtual void meterPacket(Packet *packet) override; + +}; + +} // namespace inet + +#endif /* INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMEMETER_H_ */ diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.ned b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.ned new file mode 100644 index 00000000000..d65f9d5f45d --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.ned @@ -0,0 +1,24 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +package inet.protocolelement.shaper; + +// +// This module extends the EligibilityTimeMeter with scheduler groups. +// The calculation of the eligibility time takes the eligibility times of all +// streams of the same group into account. +// +// This module is part of the asynchronous shaper infrastructure. +// +// @see ~ATS8021qFilter, ~EligibilityTimeGate, ~EligibilityTimeFilter, ~EligibilityTimeQueue, ~EligibilityTimeTag +// + +simple GroupEligibilityTimeMeter extends EligibilityTimeMeter +{ + parameters: + string groupEligibilityTimeTableModule; // relative path to the eligibilityTimeTable + @class(inet::MyEligibilityTimeMeter); +} \ No newline at end of file diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.cc b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.cc new file mode 100644 index 00000000000..bee08a5f196 --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.cc @@ -0,0 +1,56 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#include "GroupEligibilityTimeTable.h" + +namespace inet { + +Define_Module(GroupEligibilityTimeTable); + + +GroupEligibilityTimeTable::~GroupEligibilityTimeTable() +{ + groupEligibilityTimeTable = {}; +} + + +void GroupEligibilityTimeTable::updateGroupEligibilityTime(std::string group, clocktime_t newTime) +{ + if (groupEligibilityTimeTable.find(group) == groupEligibilityTimeTable.end()) + { + groupEligibilityTimeTable[group] = 0; + } + + clocktime_t currentTime = groupEligibilityTimeTable[group]; + + if (newTime > currentTime) + { + groupEligibilityTimeTable[group] = newTime; + } + +} + + +clocktime_t GroupEligibilityTimeTable::getGroupEligibilityTime(std::string group) +{ + if (groupEligibilityTimeTable.find(group) == groupEligibilityTimeTable.end()) + { + groupEligibilityTimeTable[group] = 0; + } + + return groupEligibilityTimeTable[group]; +} + + +void GroupEligibilityTimeTable::initialize(int stage) +{ + if (stage == INITSTAGE_LOCAL) + { + WATCH_MAP(groupEligibilityTimeTable); + } +} + +} //namespace inet diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.h b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.h new file mode 100644 index 00000000000..c13399a317b --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.h @@ -0,0 +1,42 @@ +// +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +#ifndef INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMETABLE_H_ +#define INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMETABLE_H_ + +#include "inet/clock/contract/ClockTime.h" + +namespace inet { + +class INET_API GroupEligibilityTimeTable : public cSimpleModule +{ + protected: + std::map groupEligibilityTimeTable; + + public: + virtual ~GroupEligibilityTimeTable(); + + /** + * Updates groupEligibilityTime for the specified group, if newTime is more recent than the time in the table. + * "Most recent value of the eligibilityTime variable from the previous frame" [Ieee802.1Qcr - 8.6.11.3.10] + */ + virtual void updateGroupEligibilityTime(std::string group, clocktime_t newTime); + + /** + * Returns the groupEligibilityTime for the corresponding group. + */ + virtual clocktime_t getGroupEligibilityTime(std::string group); + + protected: + virtual void initialize(int stage) override; + + +}; + +} //namespace inet + + +#endif /* INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMETABLE_H_ */ diff --git a/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.ned b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.ned new file mode 100644 index 00000000000..62fcdd4b2aa --- /dev/null +++ b/src/inet/protocolelement/shaper/GroupEligibilityTimeTable.ned @@ -0,0 +1,23 @@ +// Copyright (C) 2020 OpenSim Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// + +package inet.protocolelement.shaper; + +// +// This module is a table containing the group eligibility times needed +// for the GroupEligibilityTimeMeter. +// Groups are dynamically added when a frame with a new combination of ingress port and priority +// values is seen. +// +// This module is part of the asynchronous shaper infrastructure. +// +// @see ~ATS8021qFilter, ~GroupEligibilityTimeMeter, ~EligibilityTimeGate, ~EligibilityTimeFilter, ~EligibilityTimeQueue, ~EligibilityTimeTag + +simple GroupEligibilityTimeTable +{ + parameters: + @display("i=block/table"); + @class(inet::GroupEligibilityTimeTable); +}