5G-LENA nr-v4.0
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-mac-scheduler-srs-default.cc
1// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "nr-mac-scheduler-srs-default.h"
6
7#include "ns3/shuffle.h"
8#include "ns3/uinteger.h"
9
10#include <algorithm>
11
12namespace ns3
13{
14
15NS_LOG_COMPONENT_DEFINE("NrMacSchedulerSrsDefault");
16NS_OBJECT_ENSURE_REGISTERED(NrMacSchedulerSrsDefault);
17
18std::vector<uint32_t> NrMacSchedulerSrsDefault::StandardPeriodicity =
19 {2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560};
20
22{
23 m_random = CreateObject<UniformRandomVariable>();
24}
25
26int64_t
28{
29 NS_LOG_FUNCTION(this << stream);
30 m_random->SetStream(stream);
31 return 1;
32}
33
37
38TypeId
40{
41 static TypeId tid =
42 TypeId("ns3::NrMacSchedulerSrsDefault")
43 .SetParent<Object>()
44 .AddConstructor<NrMacSchedulerSrsDefault>()
45 .SetGroupName("nr")
46 .AddAttribute("StartingPeriodicity",
47 "Starting value for the periodicity",
48 UintegerValue(80),
51 MakeUintegerChecker<uint32_t>());
52 return tid;
53}
54
57{
58 NS_LOG_FUNCTION(this);
60
61 if (m_availableOffsetValues.empty())
62 {
63 return ret; // ret will be invalid
64 }
65
66 ret.m_offset = m_availableOffsetValues.back();
67 ret.m_periodicity = m_periodicity;
68 ret.m_isValid = true;
69
70 m_availableOffsetValues.pop_back();
71 return ret;
72}
73
74void
76{
77 NS_LOG_FUNCTION(this);
78 m_availableOffsetValues.push_back(offset); // Offset will be reused as soon as possible
79}
80
81bool
83 std::unordered_map<uint16_t, std::shared_ptr<NrMacSchedulerUeInfo>>* ueMap)
84{
85 NS_LOG_FUNCTION(this);
86
87 m_availableOffsetValues.clear();
88 auto it =
89 std::upper_bound(StandardPeriodicity.begin(), StandardPeriodicity.end(), m_periodicity);
90 if (it == StandardPeriodicity.end())
91 {
92 return false;
93 }
94
96 ReassignSrsValue(ueMap);
97
98 return true;
99}
100
101bool
103 std::unordered_map<uint16_t, std::shared_ptr<NrMacSchedulerUeInfo>>* ueMap)
104{
105 NS_LOG_FUNCTION(this);
106
107 m_availableOffsetValues.clear();
108 auto it =
109 std::lower_bound(StandardPeriodicity.begin(), StandardPeriodicity.end(), m_periodicity);
110 if (it == StandardPeriodicity.end())
111 {
112 return false;
113 }
114
116 ReassignSrsValue(ueMap);
117 return true;
118}
119
120void
122{
123 NS_ABORT_MSG_IF(!m_availableOffsetValues.empty(),
124 "We already started giving offset to UEs, you cannot alter the periodicity");
125
126 if (std::find(StandardPeriodicity.begin(), StandardPeriodicity.end(), start) ==
127 StandardPeriodicity.end())
128 {
129 NS_FATAL_ERROR("You cannot use "
130 << start
131 << " as periodicity; please use a standard value like "
132 "2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560"
133 " (or write your own algorithm)");
134 }
135
136 m_periodicity = start;
137 m_availableOffsetValues.resize(m_periodicity);
138
139 // Fill the available values
140 for (uint32_t i = 0; i < m_periodicity; ++i)
141 {
142 m_availableOffsetValues[i] = i;
143 }
144
145 // The below would be a candidate for a DoInitialize() method if one is ever added
146 if (m_shuffleEventId.IsPending())
147 {
148 NS_LOG_DEBUG("Canceling previously scheduled shuffle");
149 m_shuffleEventId.Cancel();
150 }
151 m_shuffleEventId = Simulator::ScheduleNow(&NrMacSchedulerSrsDefault::ShuffleOffsets, this);
152}
153
154uint32_t
156{
157 return m_periodicity;
158}
159
160void
161NrMacSchedulerSrsDefault::ShuffleOffsets()
162{
163 NS_LOG_FUNCTION(this);
164 // Shuffle the available values, so it contains the element in a random order
165 Shuffle(m_availableOffsetValues.begin(), m_availableOffsetValues.end(), m_random);
166}
167
168void
169NrMacSchedulerSrsDefault::ReassignSrsValue(
170 std::unordered_map<uint16_t, std::shared_ptr<NrMacSchedulerUeInfo>>* ueMap)
171{
172 NS_LOG_FUNCTION(this);
173
174 for (auto& ue : *ueMap)
175 {
176 auto srs = AddUe();
177
178 NS_ASSERT(srs.m_isValid);
179
180 ue.second->m_srsPeriodicity = srs.m_periodicity;
181 ue.second->m_srsOffset = srs.m_offset;
182 }
183}
184
185bool
187{
188 // Cannot increase periodicity and no offset is available
189 return m_periodicity == StandardPeriodicity.back() && m_availableOffsetValues.empty();
190}
191
192} // namespace ns3
bool IncreasePeriodicity(std::unordered_map< uint16_t, std::shared_ptr< NrMacSchedulerUeInfo > > *ueMap) override
Increase the periodicity and assign to all UEs a different offset.
bool DecreasePeriodicity(std::unordered_map< uint16_t, std::shared_ptr< NrMacSchedulerUeInfo > > *ueMap) override
Decrease the periodicity and assign to all UEs a different offset.
bool IsMaxSrsReached() const override
Check if all SRS periodicity is at the maximum allowed and all offsets have been used.
uint32_t GetStartingPeriodicity() const
Get the periodicity.
SrsPeriodicityAndOffset AddUe() override
Function called when the scheduler needs to know what is the offset and periodicy of a newly added ue...
~NrMacSchedulerSrsDefault() override
~NrMacSchedulerSrsDefault
NrMacSchedulerSrsDefault()
NrMacSchedulerSrsDefault.
void SetStartingPeriodicity(uint32_t start)
Set the Periodicity for all the UEs.
void RemoveUe(uint32_t offset) override
Function called when the scheduler has to release a previously owned periodicity and offset.
Struct to indicate to the scheduler the periodicity and the offset, in slots.
uint32_t m_periodicity
The periodicity requested (in slot).
uint32_t m_offset
The offset requested (in slot).
bool m_isValid
Indicates if the values are valid.