Skip to content

Commit

Permalink
asynchronous traffic shaper with scheduler groups
Browse files Browse the repository at this point in the history
Version of EligibilityTimeMeter with shared eligibility times between
streams of a group. Supported by GroupEligibilityTimeTable and a
Ieee8021qFilter integrating the GroupEligibilityTimeTable with the
GroupEligibilityTimeMeter.
  • Loading branch information
Teresa Lübeck authored and levy committed May 10, 2024
1 parent f6e9955 commit 80c9a23
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/inet/linklayer/ieee8021q/ATSIeee8021qFilter.ned
Original file line number Diff line number Diff line change
@@ -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");
}
}
68 changes: 68 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.cc
Original file line number Diff line number Diff line change
@@ -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<DirectionTag>();
int pcp = 0;
if (packetDirection->getDirection() == DIRECTION_INBOUND)
{
auto pcpTag = packet->findTag<PcpInd>();
pcp = pcpTag->getPcp();
}
else
{
auto pcpTag = packet->findTag<PcpReq>();
pcp = pcpTag->getPcp();
}
auto iterface = packet->findTag<InterfaceInd>();
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<EligibilityTimeTag>()->setEligibilityTime(eligibilityTime);
emitNumTokenChangedSignal(packet);
}

}

} //namespace inet
29 changes: 29 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.h
Original file line number Diff line number Diff line change
@@ -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> groupEligibilityTimeTable;

protected:
virtual void initialize(int stage) override;
virtual void meterPacket(Packet *packet) override;

};

} // namespace inet

#endif /* INET_PROTOCOLELEMENT_SHAPER_GROUPELIGIBILITYTIMEMETER_H_ */
24 changes: 24 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeMeter.ned
Original file line number Diff line number Diff line change
@@ -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);
}
56 changes: 56 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeTable.cc
Original file line number Diff line number Diff line change
@@ -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
42 changes: 42 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeTable.h
Original file line number Diff line number Diff line change
@@ -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<std::string, clocktime_t> 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_ */
23 changes: 23 additions & 0 deletions src/inet/protocolelement/shaper/GroupEligibilityTimeTable.ned
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 80c9a23

Please sign in to comment.