5G-LENA nr-v3.3-159-ga6832aa7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-mac-scheduler-lc-qos.cc
1// Copyright (c) 2023 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "nr-mac-scheduler-lc-qos.h"
6
7#include "nr-phy-mac-common.h"
8
9#include "ns3/log.h"
10
11#include <algorithm>
12#include <iostream>
13
14namespace ns3
15{
16
17NS_LOG_COMPONENT_DEFINE("NrMacSchedulerLcQos");
18NS_OBJECT_ENSURE_REGISTERED(NrMacSchedulerLcQos);
19
25
29
30TypeId
32{
33 static TypeId tid = TypeId("ns3::NrMacSchedulerLcQos")
34 .SetParent<NrMacSchedulerLcAlgorithm>()
35 .AddConstructor<NrMacSchedulerLcQos>();
36 return tid;
37}
38
39std::vector<NrMacSchedulerLcAlgorithm::Assignation>
40NrMacSchedulerLcQos::AssignBytesToDlLC(const std::unordered_map<uint8_t, LCGPtr>& ueLCG,
41 uint32_t tbs,
42 Time slotPeriod) const
43{
44 NS_LOG_FUNCTION(this);
45 GetFirst GetLCGID;
46 GetSecond GetLCG;
47
48 std::vector<NrMacSchedulerLcAlgorithm::Assignation> ret;
49
50 NS_LOG_INFO("To distribute: " << tbs << " bytes over " << ueLCG.size() << " LCG"
51 << " in Qos manner");
52
53 uint32_t bytesLeftToBeAssigned = tbs;
54 uint32_t bytesAssigned = 0;
55 uint64_t sumErabGueanteedBitRate = 0;
56
57 std::vector<std::pair<uint8_t, uint8_t>>
58 gbrActiveLCs; // vector that stores the LCG ID and the LC ID of the gbr active LCs
59 std::vector<std::pair<uint8_t, uint8_t>>
60 restActiveLCs; // vector that stores the LCG ID and the LC ID of the rest active LCs
61
62 std::vector<std::pair<uint8_t, uint32_t>>
63 AssignedBytesToGbrLCsList; // vector that stores the LC ID with the bytes assigned for the
64 // case of GBR LCs
65
66 for (const auto& lcg : ueLCG)
67 {
68 std::vector<uint8_t> ueActiveLCs = GetLCG(lcg)->GetActiveLCIds();
69 for (const auto lcId : ueActiveLCs)
70 {
71 if ((GetLCG(lcg)->GetLC(lcId)->m_resourceType ==
72 nr::LogicalChannelConfigListElement_s::QBT_DGBR ||
73 GetLCG(lcg)->GetLC(lcId)->m_resourceType ==
74 nr::LogicalChannelConfigListElement_s::QBT_GBR) &&
75 GetLCG(lcg)->GetLC(lcId)->m_eRabGuaranteedBitrateDl != UINT64_MAX)
76 {
77 gbrActiveLCs.emplace_back(GetLCGID(lcg), lcId);
78 sumErabGueanteedBitRate +=
79 (GetLCG(lcg)->GetLC(lcId)->m_eRabGuaranteedBitrateDl / 8);
80 }
81 restActiveLCs.emplace_back(GetLCGID(lcg), lcId);
82 }
83 }
84
85 if (gbrActiveLCs.size() > 1 && sumErabGueanteedBitRate >= tbs)
86 {
87 uint32_t bytesPerLcGbr;
88
89 if (bytesLeftToBeAssigned > 0)
90 {
91 NS_ASSERT(!gbrActiveLCs.empty());
92 bytesPerLcGbr = bytesLeftToBeAssigned / gbrActiveLCs.size();
93
94 for (const auto& lcg : ueLCG)
95 {
96 for (auto& itGbrActiveLCs : gbrActiveLCs)
97 {
98 if (itGbrActiveLCs.first == GetLCGID(lcg))
99 {
100 AssignedBytesToGbrLCsList.emplace_back(itGbrActiveLCs.second,
101 bytesPerLcGbr);
102 }
103 }
104 }
105 bytesLeftToBeAssigned = 0;
106 }
107 }
108 else if (!gbrActiveLCs.empty())
109 {
110 for (const auto& lcg : ueLCG)
111 {
112 for (auto& itGbrActiveLCs : gbrActiveLCs)
113 {
114 if (itGbrActiveLCs.first == GetLCGID(lcg))
115 {
116 NS_ASSERT_MSG(
117 GetLCG(lcg)->GetLC(itGbrActiveLCs.second)->m_eRabGuaranteedBitrateDl !=
118 UINT64_MAX,
119 "LC is not guaranteed bit rate!");
120
121 uint32_t bytes = std::min(
122 static_cast<uint32_t>(
123 slotPeriod.GetSeconds() *
124 (GetLCG(lcg)->GetLC(itGbrActiveLCs.second)->m_eRabGuaranteedBitrateDl /
125 8)),
126 GetLCG(lcg)->GetLC(itGbrActiveLCs.second)->GetTotalSize());
127
128 bytesAssigned = bytes >= bytesLeftToBeAssigned ? bytesLeftToBeAssigned : bytes;
129
130 AssignedBytesToGbrLCsList.emplace_back(itGbrActiveLCs.second, bytesAssigned);
131
132 NS_ASSERT(bytesLeftToBeAssigned >= bytesAssigned); // check
133 bytesLeftToBeAssigned -= bytesAssigned;
134 }
135 }
136 }
137 }
138
139 uint32_t bytesPerLc;
140
141 if (!restActiveLCs.empty() && bytesLeftToBeAssigned > 0)
142 {
143 NS_ASSERT(!restActiveLCs.empty());
144 bytesPerLc = bytesLeftToBeAssigned / restActiveLCs.size();
145
146 for (const auto& lcg : ueLCG)
147 {
148 for (auto& itRestActiveLCs : restActiveLCs)
149 {
150 if (itRestActiveLCs.first == GetLCGID(lcg))
151 {
152 bool erabGbrTrue = false;
153
154 for (auto& it : AssignedBytesToGbrLCsList)
155 {
156 if (it.first == itRestActiveLCs.second && GetLCGID(lcg) == 1)
157 {
158 it.second += bytesPerLc;
159 erabGbrTrue = true;
160 break;
161 }
162 }
163
164 if (!erabGbrTrue)
165 {
166 NS_LOG_DEBUG("LC : " << +itRestActiveLCs.second
167 << " bytes: " << bytesPerLc);
168 ret.emplace_back(GetLCGID(lcg), itRestActiveLCs.second, bytesPerLc);
169 }
170 }
171 }
172 }
173 }
174
175 for (auto& it : AssignedBytesToGbrLCsList)
176 {
177 NS_LOG_DEBUG("LC : " << +it.first << " bytes: " << it.second);
178 ret.emplace_back(1, it.first, it.second);
179 }
180
181 return ret;
182}
183
184std::vector<NrMacSchedulerLcAlgorithm::Assignation>
185NrMacSchedulerLcQos::AssignBytesToUlLC(const std::unordered_map<uint8_t, LCGPtr>& ueLCG,
186 uint32_t tbs) const
187{
188 NS_LOG_FUNCTION(this);
189 GetFirst GetLCGID;
190 GetSecond GetLCG;
191
192 std::vector<NrMacSchedulerLcAlgorithm::Assignation> ret;
193
194 uint32_t activeLc = 0;
195 for (const auto& lcg : ueLCG)
196 {
197 std::vector<uint8_t> lcs = GetLCG(lcg)->GetLCId();
198 for (const auto& lcId : lcs)
199 {
200 if (GetLCG(lcg)->GetTotalSizeOfLC(lcId) > 0)
201 {
202 ++activeLc;
203 }
204 }
205 }
206
207 if (activeLc == 0)
208 {
209 return ret;
210 }
211
212 uint32_t amountPerLC = tbs / activeLc;
213 NS_LOG_INFO("Total LC: " << activeLc << " each one will receive " << amountPerLC << " bytes");
214
215 for (const auto& lcg : ueLCG)
216 {
217 std::vector<uint8_t> lcs = GetLCG(lcg)->GetLCId();
218 for (const auto& lcId : lcs)
219 {
220 if (GetLCG(lcg)->GetTotalSizeOfLC(lcId) > 0)
221 {
222 NS_LOG_INFO("Assigned to LCID " << static_cast<uint32_t>(lcId) << " inside LCG "
223 << static_cast<uint32_t>(GetLCGID(lcg))
224 << " an amount of " << amountPerLC << " B");
225 ret.emplace_back(GetLCGID(lcg), lcId, amountPerLC);
226 }
227 }
228 }
229
230 return ret;
231}
232
233} // namespace ns3
This class is the interface for the creation of various scheduling algorithms for the distribution of...
~NrMacSchedulerLcQos() override
NrMacSchedulerLcQos deconstructor.
static TypeId GetTypeId()
Get the type ID.
NrMacSchedulerLcQos()
NrMacSchedulerLcQos constructor.
std::vector< Assignation > AssignBytesToDlLC(const std::unordered_map< uint8_t, LCGPtr > &ueLCG, uint32_t tbs, Time slotPeriod) const override
Method to decide how to distribute the assigned bytes to the different LCs for the DL direction....
std::vector< Assignation > AssignBytesToUlLC(const std::unordered_map< uint8_t, LCGPtr > &ueLCG, uint32_t tbs) const override
Method to decide how to distribute the assigned bytes to the different LCs for the UL direction....