gtpu - leverage byte_buffer_pool to store buffered sdus in gtpu

master
Francisco 4 years ago committed by Francisco Paisana
parent bdc5094e17
commit cfd24f6a0e

@ -13,7 +13,7 @@
#ifndef SRSRAN_BOUNDED_VECTOR_H
#define SRSRAN_BOUNDED_VECTOR_H
#include <cassert>
#include "srsran/common/srsran_assert.h"
#include <iterator>
#include <memory>
#include <type_traits>
@ -87,22 +87,22 @@ public:
// Element access
T& operator[](std::size_t i)
{
assert(i < size_ && "Array index is out of bounds.");
srsran_assert(i < size_, "Array index is out of bounds.");
return reinterpret_cast<T&>(buffer[i]);
}
const T& operator[](std::size_t i) const
{
assert(i < size_ && "Array index is out of bounds.");
srsran_assert(i < size_, "Array index is out of bounds.");
return reinterpret_cast<const T&>(buffer[i]);
}
T& back()
{
assert(size_ > 0 && "Trying to get back of empty array.");
srsran_assert(size_ > 0, "Trying to get back of empty array.");
return *(begin() + size_ - 1);
}
const T& back() const
{
assert(size_ > 0 && "Trying to get back of empty array.");
srsran_assert(size_ > 0, "Trying to get back of empty array.");
return *(begin() + size_ - 1);
}
T& front() { return (*this)[0]; }
@ -130,8 +130,8 @@ public:
}
iterator erase(iterator pos)
{
assert(pos >= this->begin() && "Iterator to erase is out of bounds.");
assert(pos < this->end() && "Erasing at past-the-end iterator.");
srsran_assert(pos >= this->begin(), "Iterator to erase is out of bounds.");
srsran_assert(pos < this->end(), "Erasing at past-the-end iterator.");
iterator ret = pos;
std::move(pos + 1, end(), pos);
pop_back();
@ -139,9 +139,9 @@ public:
}
iterator erase(iterator it_start, iterator it_end)
{
assert(it_start >= begin() && "Range to erase is out of bounds.");
assert(it_start <= it_end && "Trying to erase invalid range.");
assert(it_end <= end() && "Trying to erase past the end.");
srsran_assert(it_start >= begin(), "Range to erase is out of bounds.");
srsran_assert(it_start <= it_end, "Trying to erase invalid range.");
srsran_assert(it_end <= end(), "Trying to erase past the end.");
iterator ret = it_start;
// Shift all elts down.
@ -154,14 +154,14 @@ public:
{
static_assert(std::is_copy_constructible<T>::value, "T must be copy-constructible");
size_++;
assert(size_ <= MAX_N);
srsran_assert(size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
new (&back()) T(value);
}
void push_back(T&& value)
{
static_assert(std::is_move_constructible<T>::value, "T must be move-constructible");
size_++;
assert(size_ <= MAX_N);
srsran_assert(size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
new (&back()) T(std::move(value));
}
template <typename... Args>
@ -169,12 +169,12 @@ public:
{
static_assert(std::is_constructible<T, Args&&...>::value, "Passed arguments to emplace_back are invalid");
size_++;
assert(size_ <= MAX_N);
srsran_assert(size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
new (&back()) T(std::forward<Args>(args)...);
}
void pop_back()
{
assert(size_ > 0 && "Trying to erase element from empty vector.");
srsran_assert(size_ > 0, "Trying to erase element from empty vector.");
back().~T();
size_--;
}
@ -210,21 +210,21 @@ private:
void append(const_iterator it_begin, const_iterator it_end)
{
size_type N = std::distance(it_begin, it_end);
assert(N + size_ <= MAX_N);
srsran_assert(N + size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
std::uninitialized_copy(it_begin, it_end, end());
size_ += N;
}
void append(size_type N, const T& element)
{
static_assert(std::is_copy_constructible<T>::value, "T must be copy-constructible");
assert(N + size_ <= MAX_N);
srsran_assert(N + size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
std::uninitialized_fill_n(end(), N, element);
size_ += N;
}
void append(size_type N)
{
static_assert(std::is_default_constructible<T>::value, "T must be default-constructible");
assert(N + size_ <= MAX_N);
srsran_assert(N + size_ <= MAX_N, "bounded vector maximum size=%zd was exceeded", MAX_N);
for (size_type i = size_; i < size_ + N; ++i) {
new (&buffer[i]) T();
}

@ -62,6 +62,8 @@ class concurrent_fixed_memory_pool
}
public:
const static size_t BLOCK_SIZE = ObjSize;
concurrent_fixed_memory_pool(const concurrent_fixed_memory_pool&) = delete;
concurrent_fixed_memory_pool(concurrent_fixed_memory_pool&&) = delete;
concurrent_fixed_memory_pool& operator=(const concurrent_fixed_memory_pool&) = delete;

@ -14,6 +14,7 @@
#define SRSRAN_BUFFER_POOL_H
#include "byte_buffer.h"
#include "srsran/adt/bounded_vector.h"
#include <algorithm>
#include <map>
#include <pthread.h>
@ -183,6 +184,49 @@ inline unique_byte_buffer_t make_byte_buffer(const char* debug_ctxt) noexcept
return buffer;
}
namespace detail {
struct byte_buffer_pool_deleter {
void operator()(void* ptr) { byte_buffer_pool::get_instance()->deallocate_node(ptr); }
};
} // namespace detail
template <typename T>
struct byte_buffer_pool_ptr {
static_assert(sizeof(T) <= byte_buffer_pool::BLOCK_SIZE, "pool_bounded_vector does not fit buffer pool block size");
public:
byte_buffer_pool_ptr() = default;
void reset() { ptr.reset(); }
T* operator->() { return ptr.get(); }
const T* operator->() const { return ptr.get(); }
T& operator*() { return *ptr; }
const T& operator*() const { return *ptr; }
template <typename... CtorArgs>
void emplace(CtorArgs&&... args)
{
ptr.reset(make(std::forward<CtorArgs>(args)...).ptr.release());
}
template <typename... CtorArgs>
static byte_buffer_pool_ptr<T> make(CtorArgs&&... args)
{
void* memblock = byte_buffer_pool::get_instance()->allocate_node(sizeof(T));
if (memblock == nullptr) {
return byte_buffer_pool_ptr<T>();
}
new (memblock) T(std::forward<CtorArgs>(args)...);
byte_buffer_pool_ptr<T> ret;
ret.ptr = std::unique_ptr<T, detail::byte_buffer_pool_deleter>(static_cast<T*>(memblock),
detail::byte_buffer_pool_deleter());
return ret;
};
private:
std::unique_ptr<T, detail::byte_buffer_pool_deleter> ptr;
};
} // namespace srsran
#endif // SRSRAN_BUFFER_POOL_H

@ -76,7 +76,7 @@ struct rlc_ringbuffer_t {
rlc_ringbuffer_t() { clear(); }
T& add_pdu(size_t sn)
{
srsran_expect(not has_sn(sn), "The same SN=%d should not be added twice", sn);
srsran_expect(not has_sn(sn), "The same SN=%zd should not be added twice", sn);
window[sn].rlc_sn = sn;
active_flag[sn] = true;
count++;
@ -84,14 +84,14 @@ struct rlc_ringbuffer_t {
}
void remove_pdu(size_t sn)
{
srsran_expect(has_sn(sn), "The removed SN=%d is not in the window", sn);
srsran_expect(has_sn(sn), "The removed SN=%zd is not in the window", sn);
window[sn] = {};
active_flag[sn] = false;
count--;
}
T& operator[](size_t sn)
{
srsran_expect(has_sn(sn), "The accessed SN=%d is not in the window", sn);
srsran_expect(has_sn(sn), "The accessed SN=%zd is not in the window", sn);
return window[sn];
}
size_t size() const { return count; }

@ -49,7 +49,7 @@ struct gtpu_tunnel {
uint32_t fwd_teid_in = 0; ///< forward Rx SDUs to this TEID
uint32_t prior_teid_in = 0; ///< buffer bearer SDUs until this TEID receives an End Marker
srsran::unique_timer rx_timer;
std::vector<std::pair<uint32_t, srsran::unique_byte_buffer_t> > buffer;
srsran::byte_buffer_pool_ptr<srsran::bounded_vector<std::pair<uint32_t, srsran::unique_byte_buffer_t>, 512> > buffer;
};
class gtpu_tunnel_manager

@ -322,6 +322,7 @@ uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t
if (props->flush_before_teidin_present) {
// GTPU should wait for the bearer ctxt to arrive before sending SDUs from DL tunnel to PDCP
new_tun->dl_enabled = false;
new_tun->buffer.emplace();
// GTPU should not forward SDUs from main tunnel until the SeNB-TeNB tunnel has been flushed
gtpu_tunnel* after_tun = tunnels.find_tunnel(props->flush_before_teidin);
if (after_tun == nullptr) {
@ -330,6 +331,7 @@ uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t
return -1;
}
after_tun->dl_enabled = false;
after_tun->buffer.emplace();
after_tun->prior_teid_in_present = true;
after_tun->prior_teid_in = teid_in;
@ -378,17 +380,17 @@ void gtpu::set_tunnel_status(uint32_t teidin, bool dl_active)
tun->dl_enabled = dl_active;
if (dl_active and not old_state) {
logger.info(
"Activating GTPU tunnel rnti=0x%x,TEID=%d. %d SDUs currently buffered", tun->rnti, teidin, tun->buffer.size());
"Activating GTPU tunnel rnti=0x%x,TEID=%d. %d SDUs currently buffered", tun->rnti, teidin, tun->buffer->size());
std::stable_sort(
tun->buffer.begin(),
tun->buffer.end(),
tun->buffer->begin(),
tun->buffer->end(),
[](const std::pair<uint32_t, srsran::unique_byte_buffer_t>& lhs,
const std::pair<uint32_t, srsran::unique_byte_buffer_t>& rhs) { return lhs.first < rhs.first; });
for (auto& sdu_it : tun->buffer) {
for (auto& sdu_it : *tun->buffer) {
pdcp->write_sdu(
tun->rnti, tun->lcid, std::move(sdu_it.second), sdu_it.first == undefined_pdcp_sn ? -1 : sdu_it.first);
}
tun->buffer.clear();
tun->buffer.reset();
}
}
@ -513,7 +515,7 @@ void gtpu::handle_msg_data_pdu(const gtpu_header_t& header, gtpu_tunnel& rx_tunn
pdcp_sn = (header.ext_buffer[1] << 8U) + header.ext_buffer[2];
}
if (not rx_tunnel.dl_enabled) {
rx_tunnel.buffer.push_back(std::make_pair(pdcp_sn, std::move(pdu)));
rx_tunnel.buffer->push_back(std::make_pair(pdcp_sn, std::move(pdu)));
} else {
pdcp->write_sdu(rnti, lcid, std::move(pdu), pdcp_sn == undefined_pdcp_sn ? -1 : (int)pdcp_sn);
}

Loading…
Cancel
Save