Commit d20cccca authored by aligungr's avatar aligungr

Performance improvements

parent 9c90d924
......@@ -185,7 +185,6 @@ void RlsControlTask::handleDownlinkRrcDelivery(int ueId, uint32_t pduId, rrc::Rr
m_pduMap[pduId].endPointId = ueId;
m_pduMap[pduId].id = pduId;
m_pduMap[pduId].pdu = data.copy();
m_pduMap[pduId].rrcChannel = channel;
m_pduMap[pduId].sentTime = utils::CurrentTimeMillis();
}
......@@ -223,7 +222,7 @@ void RlsControlTask::onAckControlTimerExpired()
if (delta > MAX_PDU_TTL)
{
transmissionFailureIds.push_back(pdu.first);
transmissionFailures.push_back(std::move(pdu.second));
transmissionFailures.push_back(pdu.second);
}
}
......
......@@ -18,7 +18,6 @@ namespace rls
struct PduInfo
{
uint32_t id{};
OctetString pdu;
rrc::RrcChannel rrcChannel{};
int64_t sentTime{};
int endPointId{};
......
......@@ -13,6 +13,18 @@
namespace rls
{
static void EncodeDefault(uint8_t *buffer, rls::EMessageType msgType, uint64_t sti)
{
buffer[0] = 0x03; // (Just for old RLS compatibility)
buffer[1] = cons::Major;
buffer[2] = cons::Minor;
buffer[3] = cons::Patch;
buffer[4] = static_cast<uint8_t>(msgType);
octet8::SetTo(octet8{sti}, buffer + 5);
}
int EncodeRlsMessage(const RlsMessage &msg, uint8_t *buffer)
{
buffer[0] = 0x03; // (Just for old RLS compatibility)
......@@ -166,4 +178,44 @@ void DecodePduTransmission(const uint8_t *buffer, size_t size, EPduType &pduType
pduData = buffer + view.currentIndex() + 13;
}
void EncodeHeartbeat(CompoundBuffer &buffer, uint64_t sti, const Vector3 &simPos)
{
buffer.reset();
EncodeDefault(buffer.cmAddress(), EMessageType::HEARTBEAT, sti);
octet4::SetTo(octet4{simPos.x}, buffer.cmAddress() + 13);
octet4::SetTo(octet4{simPos.y}, buffer.cmAddress() + 17);
octet4::SetTo(octet4{simPos.z}, buffer.cmAddress() + 21);
buffer.setCmSize(25);
}
void EncodePduTransmissionAck(CompoundBuffer &buffer, uint64_t sti, const std::vector<uint32_t> &pduIds)
{
buffer.reset();
uint8_t *data = buffer.cmAddress();
EncodeDefault(data, EMessageType::PDU_TRANSMISSION_ACK, sti);
octet4::SetTo(octet4{pduIds.size()}, data + 13);
data += 17;
for (auto pduId : pduIds)
{
octet4::SetTo(octet4{pduId}, data);
data += 4;
}
buffer.setCmSize(17ull + pduIds.size() * 4ull);
}
void EncodePduTransmission(CompoundBuffer &buffer, uint64_t sti, rls::EPduType pduType, uint32_t payload,
uint32_t pduId)
{
buffer.setTailCapacity(26);
auto tail = buffer.tailAddress();
EncodeDefault(tail, EMessageType::PDU_TRANSMISSION, sti);
tail[13] = static_cast<uint8_t>(pduType);
octet4::SetTo(octet4{pduId}, tail + 14);
octet4::SetTo(octet4{payload}, tail + 18);
octet4::SetTo(octet4{buffer.cmSize()}, tail + 22);
}
} // namespace rls
......@@ -10,8 +10,11 @@
#include <cstdint>
#include <memory>
#include <unordered_map>
#include <vector>
#include <utils/common_types.hpp>
#include <utils/compound_buffer.hpp>
#include <utils/octet_string.hpp>
#include <utils/octet_view.hpp>
......@@ -39,7 +42,7 @@ enum class EPduType : uint8_t
DATA
};
struct RlsMessage
struct RlsMessage // TODO: remove
{
const EMessageType msgType;
const uint64_t sti{};
......@@ -90,9 +93,14 @@ struct RlsPduTransmissionAck : RlsMessage
}
};
int EncodeRlsMessage(const RlsMessage &msg, uint8_t *buffer);
int EncodeRlsMessage(const RlsMessage &msg, uint8_t *buffer); // todo: remove
std::unique_ptr<RlsMessage> DecodeRlsMessage(const OctetView &stream); // todo: remove
void EncodeHeartbeat(CompoundBuffer &buffer, uint64_t sti, const Vector3 &simPos);
void EncodePduTransmissionAck(CompoundBuffer &buffer, uint64_t sti, const std::vector<uint32_t> &pduIds);
void EncodePduTransmission(CompoundBuffer &buffer, uint64_t sti, rls::EPduType pduType, uint32_t payload,
uint32_t pduId);
bool DecodeRlsHeader(const uint8_t *buffer, size_t size, EMessageType &msgType, uint64_t &sti);
void DecodeHeartbeatAck(const uint8_t *buffer, size_t size, int &dbm);
OctetView DecodePduTransmissionAck(const uint8_t *buffer, size_t size);
......
......@@ -106,9 +106,9 @@ void NasLayer::handleNasDelivery(const OctetString &data)
m_mm->receiveNasMessage(*nasMessage);
}
void NasLayer::handleUplinkDataRequest(int psi, uint8_t* buffer, size_t size)
void NasLayer::handleUplinkDataRequest(int psi, CompoundBuffer &buffer)
{
m_sm->handleUplinkDataRequest(psi, buffer, size);
m_sm->handleUplinkDataRequest(psi, buffer);
}
void NasLayer::handleDownlinkDataRequest(int psi, const uint8_t *buffer, size_t size)
......
......@@ -14,6 +14,7 @@
#include <ue/nas/sm/sm.hpp>
#include <ue/nas/usim/usim.hpp>
#include <ue/types.hpp>
#include <utils/compound_buffer.hpp>
#include <utils/nts.hpp>
namespace nr::ue
......@@ -48,8 +49,8 @@ class NasLayer
void handleRadioLinkFailure();
void handleRrcEstablishmentFailure();
void handleActiveCellChange(const Tai &prevTai);
void handleNasDelivery(const OctetString& data);
void handleUplinkDataRequest(int psi, uint8_t* buffer, size_t size);
void handleNasDelivery(const OctetString &data);
void handleUplinkDataRequest(int psi, CompoundBuffer &buffer);
void handleDownlinkDataRequest(int psi, const uint8_t *buffer, size_t size);
};
......
......@@ -31,7 +31,7 @@ void NasSm::onTimerTick()
}
}
void NasSm::handleUplinkDataRequest(int psi, uint8_t* buffer, size_t size)
void NasSm::handleUplinkDataRequest(int psi, CompoundBuffer &buffer)
{
auto state = m_mm->m_mmSubState;
if (state != EMmSubState::MM_REGISTERED_INITIATED_PS && state != EMmSubState::MM_REGISTERED_NORMAL_SERVICE &&
......@@ -54,7 +54,7 @@ void NasSm::handleUplinkDataRequest(int psi, uint8_t* buffer, size_t size)
handleUplinkStatusChange(psi, false);
}
m_ue->rlsCtl->handleUplinkDataDelivery(psi, buffer, size);
m_ue->rlsCtl->handleUplinkDataDelivery(psi, buffer);
}
else
{
......
......@@ -91,7 +91,7 @@ class NasSm
private: /* Service Access Point */
void onTimerTick();
void handleUplinkDataRequest(int psi, uint8_t* buffer, size_t size);
void handleUplinkDataRequest(int psi, CompoundBuffer &buffer);
void handleDownlinkDataRequest(int psi, const uint8_t *buffer, size_t size);
void setupTunInterface(const PduSession &pduSession);
};
......
......@@ -8,7 +8,7 @@ static constexpr const int MAX_PDU_TTL = 3000;
namespace nr::ue
{
RlsCtlLayer::RlsCtlLayer(UeTask *ue) : m_ue{ue}, m_servingCell{}, m_pduMap{}, m_pendingAck{}
RlsCtlLayer::RlsCtlLayer(UeTask *ue) : m_ue{ue}, m_servingCell{}, m_pduMap{}, m_pendingAck{}, m_cBuffer{8192}
{
m_logger = ue->logBase->makeUniqueLogger(ue->config->getLoggerPrefix() + "rls-ctl");
}
......@@ -76,29 +76,21 @@ void RlsCtlLayer::handleUplinkRrcDelivery(int cellId, uint32_t pduId, rrc::RrcCh
m_pduMap[pduId].endPointId = cellId;
m_pduMap[pduId].id = pduId;
m_pduMap[pduId].pdu = data.copy();
m_pduMap[pduId].rrcChannel = channel;
m_pduMap[pduId].sentTime = utils::CurrentTimeMillis();
}
rls::RlsPduTransmission msg{m_ue->shCtx.sti};
msg.pduType = rls::EPduType::RRC;
msg.pdu = std::move(data);
msg.payload = static_cast<uint32_t>(channel);
msg.pduId = pduId;
m_ue->rlsUdp->send(cellId, msg);
m_cBuffer.reset();
m_cBuffer.setCmSize(static_cast<size_t>(data.length()));
std::memcpy(m_cBuffer.cmAddress(), data.data(), m_cBuffer.cmSize());
rls::EncodePduTransmission(m_cBuffer, m_ue->shCtx.sti, rls::EPduType::RRC, static_cast<uint32_t>(channel), pduId);
m_ue->rlsUdp->send(cellId, m_cBuffer);
}
void RlsCtlLayer::handleUplinkDataDelivery(int psi, uint8_t *buffer, size_t size)
void RlsCtlLayer::handleUplinkDataDelivery(int psi, CompoundBuffer &buffer)
{
rls::RlsPduTransmission msg{m_ue->shCtx.sti};
msg.pduType = rls::EPduType::DATA;
msg.pdu = OctetString::FromArray(buffer, size);
msg.payload = static_cast<uint32_t>(psi);
msg.pduId = 0;
m_ue->rlsUdp->send(m_servingCell, msg);
rls::EncodePduTransmission(buffer, m_ue->shCtx.sti, rls::EPduType::DATA, static_cast<uint32_t>(psi), 0);
m_ue->rlsUdp->send(m_servingCell, buffer);
}
void RlsCtlLayer::onAckControlTimerExpired()
......@@ -114,7 +106,7 @@ void RlsCtlLayer::onAckControlTimerExpired()
if (delta > MAX_PDU_TTL)
{
transmissionFailureIds.push_back(pdu.first);
transmissionFailures.push_back(std::move(pdu.second));
transmissionFailures.push_back(pdu.second);
}
}
......@@ -127,19 +119,15 @@ void RlsCtlLayer::onAckControlTimerExpired()
void RlsCtlLayer::onAckSendTimerExpired()
{
auto copy = m_pendingAck;
m_pendingAck.clear();
for (auto &item : copy)
for (auto &item : m_pendingAck)
{
if (!item.second.empty())
continue;
rls::RlsPduTransmissionAck msg{m_ue->shCtx.sti};
msg.pduIds = std::move(item.second);
m_ue->rlsUdp->send(item.first, msg);
rls::EncodePduTransmissionAck(m_cBuffer, m_ue->shCtx.sti, item.second);
m_ue->rlsUdp->send(item.first, m_cBuffer);
}
m_pendingAck.clear();
}
void RlsCtlLayer::assignCurrentCell(int cellId)
......
......@@ -11,9 +11,10 @@
#include <unordered_map>
#include <vector>
#include <lib/rrc/rrc.hpp>
#include <lib/rls/rls_base.hpp>
#include <lib/rrc/rrc.hpp>
#include <ue/types.hpp>
#include <utils/compound_buffer.hpp>
#include <utils/nts.hpp>
namespace nr::ue
......@@ -27,6 +28,7 @@ class RlsCtlLayer
int m_servingCell;
std::unordered_map<uint32_t, rls::PduInfo> m_pduMap;
std::unordered_map<int, std::vector<uint32_t>> m_pendingAck;
CompoundBuffer m_cBuffer;
public:
explicit RlsCtlLayer(UeTask *ue);
......@@ -41,7 +43,7 @@ class RlsCtlLayer
void handleRlsMessage(int cellId, rls::EMessageType msgType, uint8_t *buffer, size_t size);
void assignCurrentCell(int cellId);
void handleUplinkRrcDelivery(int cellId, uint32_t pduId, rrc::RrcChannel channel, OctetString &&data);
void handleUplinkDataDelivery(int psi, uint8_t *buffer, size_t size);
void handleUplinkDataDelivery(int psi, CompoundBuffer &buffer);
};
} // namespace nr::ue
\ No newline at end of file
......@@ -7,7 +7,7 @@
#include <utils/common.hpp>
#include <utils/constants.hpp>
static constexpr const int SEND_BUFFER = 16384;
static constexpr const int BUFFER_SIZE = 2048ull;
static constexpr const int LOOP_PERIOD = 1000;
static constexpr const int HEARTBEAT_THRESHOLD = 2000; // (LOOP_PERIOD + RECEIVE_TIMEOUT)'dan büyük olmalı
......@@ -15,8 +15,7 @@ namespace nr::ue
{
RlsUdpLayer::RlsUdpLayer(UeTask *ue)
: m_ue{ue}, m_sendBuffer{new uint8_t[SEND_BUFFER]}, m_searchSpace{}, m_cells{}, m_cellIdToSti{}, m_lastLoop{},
m_cellIdCounter{}
: m_ue{ue}, m_cBuffer(BUFFER_SIZE), m_searchSpace{}, m_cells{}, m_cellIdToSti{}, m_lastLoop{}, m_cellIdCounter{}
{
m_logger = ue->logBase->makeUniqueLogger(ue->config->getLoggerPrefix() + "rls-udp");
......@@ -41,24 +40,21 @@ void RlsUdpLayer::checkHeartbeat()
}
}
void RlsUdpLayer::sendRlsPdu(const InetAddress &address, const rls::RlsMessage &msg)
void RlsUdpLayer::sendRlsPdu(const InetAddress &address, CompoundBuffer &buffer)
{
int n = rls::EncodeRlsMessage(msg, m_sendBuffer.get());
int version = address.getIpVersion();
if (version != 4 && version != 6)
throw std::runtime_error{"UdpServer::Send failure: Invalid IP version"};
m_ue->fdBase->sendTo(version == 4 ? FdBase::RLS_IP4 : FdBase::RLS_IP6, m_sendBuffer.get(), static_cast<size_t>(n),
address);
m_ue->fdBase->sendTo(version == 4 ? FdBase::RLS_IP4 : FdBase::RLS_IP6, buffer.data(), buffer.size(), address);
}
void RlsUdpLayer::send(int cellId, const rls::RlsMessage &msg)
void RlsUdpLayer::send(int cellId, CompoundBuffer &buffer)
{
if (m_cellIdToSti.count(cellId))
{
auto sti = m_cellIdToSti[cellId];
sendRlsPdu(m_cells[sti].address, msg);
sendRlsPdu(m_cells[sti].address, buffer);
}
}
......@@ -138,12 +134,10 @@ void RlsUdpLayer::heartbeatCycle(uint64_t time, const Vector3 &simPos)
for (auto cell : toRemove)
onSignalChangeOrLost(cell);
rls::EncodeHeartbeat(m_cBuffer, m_ue->shCtx.sti, simPos);
for (auto &address : m_searchSpace)
{
rls::RlsHeartBeat msg{m_ue->shCtx.sti};
msg.simPos = simPos;
sendRlsPdu(address, msg);
}
sendRlsPdu(address, m_cBuffer);
}
} // namespace nr::ue
......@@ -17,6 +17,7 @@
#include <lib/udp/server_task.hpp>
#include <ue/types.hpp>
#include <utils/nts.hpp>
#include <utils/compound_buffer.hpp>
namespace nr::ue
{
......@@ -35,7 +36,7 @@ class RlsUdpLayer
private:
UeTask *m_ue;
std::unique_ptr<Logger> m_logger;
std::unique_ptr<uint8_t[]> m_sendBuffer;
CompoundBuffer m_cBuffer;
std::vector<InetAddress> m_searchSpace;
std::unordered_map<uint64_t, CellInfo> m_cells;
std::unordered_map<int, uint64_t> m_cellIdToSti;
......@@ -50,14 +51,14 @@ class RlsUdpLayer
~RlsUdpLayer();
private:
void sendRlsPdu(const InetAddress &address, const rls::RlsMessage &msg);
void sendRlsPdu(const InetAddress &address, CompoundBuffer &buffer);
void onSignalChangeOrLost(int cellId);
void heartbeatCycle(uint64_t time, const Vector3 &simPos);
public:
void checkHeartbeat();
void send(int cellId, const rls::RlsMessage &msg);
void receiveRlsPdu(const InetAddress &address, uint8_t* buffer, size_t size);
void send(int cellId, CompoundBuffer &buffer);
void receiveRlsPdu(const InetAddress &address, uint8_t *buffer, size_t size);
};
} // namespace nr::ue
......@@ -20,12 +20,12 @@ struct TimerPeriod
static constexpr const int SWITCH_OFF = 500;
};
#define BUFFER_SIZE 65535
#define BUFFER_SIZE 32768ull
namespace nr::ue
{
ue::UeTask::UeTask(std::unique_ptr<UeConfig> &&config)
ue::UeTask::UeTask(std::unique_ptr<UeConfig> &&config) : m_cBuffer(BUFFER_SIZE)
{
this->logBase = std::make_unique<LogBase>("logs/ue-" + config->getNodeName() + ".log");
this->config = std::move(config);
......@@ -85,8 +85,10 @@ bool UeTask::onLoop()
{
if (fdId >= FdBase::PS_START && fdId <= FdBase::PS_END)
{
size_t n = fdBase->read(fdId, m_buffer.get(), BUFFER_SIZE);
nas->handleUplinkDataRequest(fdId - FdBase::PS_START, m_buffer.get(), n);
size_t n = fdBase->read(fdId, m_cBuffer.cmAddress(), m_cBuffer.cmCapacity());
m_cBuffer.reset();
m_cBuffer.setCmSize(n);
nas->handleUplinkDataRequest(fdId - FdBase::PS_START, m_cBuffer);
}
else if (fdId == FdBase::RLS_IP4 || fdId == FdBase::RLS_IP6)
{
......
......@@ -25,6 +25,7 @@
#include <ue/rrc/layer.hpp>
#include <ue/tun/layer.hpp>
#include <utils/common_types.hpp>
#include <utils/compound_buffer.hpp>
#include <utils/fd_base.hpp>
#include <utils/logger.hpp>
#include <utils/nts.hpp>
......@@ -52,6 +53,7 @@ class UeTask
bool m_immediateCycle;
std::unique_ptr<uint8_t[]> m_buffer;
std::unique_ptr<UeCmdHandler> m_cmdHandler;
CompoundBuffer m_cBuffer;
public:
std::unique_ptr<UeConfig> config;
......
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#include "compound_buffer.hpp"
//
// This file is a part of UERANSIM open source project.
// Copyright (c) 2021 ALİ GÜNGÖR.
//
// The software and all associated files are licensed under GPL-3.0
// and subject to the terms and conditions defined in LICENSE file.
//
#pragma once
#include <cstdint>
#include <cstdlib>
#include <utils/octet_view.hpp>
class CompoundBuffer
{
private:
uint8_t *m_buffer;
size_t m_capacity;
size_t m_cursor;
size_t m_cmSize;
size_t m_tailCapacity;
public:
explicit inline CompoundBuffer(size_t capacity)
: m_buffer{new uint8_t[capacity]}, m_capacity{capacity}, m_cursor{capacity / 2}, m_cmSize{}, m_tailCapacity{}
{
}
CompoundBuffer(const CompoundBuffer &v) = delete;
inline ~CompoundBuffer()
{
delete[] m_buffer;
}
public:
inline void reset()
{
m_cursor = m_capacity / 2;
m_cmSize = 0;
m_tailCapacity = 0;
}
inline uint8_t *cmAddress()
{
return m_buffer + m_cursor;
}
[[nodiscard]] inline size_t cmCapacity() const
{
return m_capacity - m_cursor;
}
inline void setCmSize(size_t size)
{
m_cmSize = size;
}
[[nodiscard]] size_t cmSize() const
{
return m_cmSize;
}
inline void setTailCapacity(size_t capacity)
{
m_tailCapacity = capacity;
}
[[nodiscard]] inline size_t tailCapacity() const
{
return m_tailCapacity;
}
inline uint8_t *tailAddress()
{
return cmAddress() - m_tailCapacity;
}
inline uint8_t *data()
{
return tailAddress();
}
[[nodiscard]] inline size_t size() const
{
return m_tailCapacity + m_cmSize;
}
};
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment