From 0c7c317be5d75145120f896a19ba77c5f1dab130 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 5 Feb 2021 17:04:05 +0000 Subject: [PATCH] refactor byte_buffer class and move it to separate file --- lib/include/srslte/common/buffer_pool.h | 8 +- lib/include/srslte/common/byte_buffer.h | 246 ++++++++++++++++++ lib/include/srslte/common/common.h | 225 ---------------- lib/include/srslte/common/interfaces_common.h | 1 + lib/src/asn1/gtpc.cc | 2 +- lib/src/common/CMakeLists.txt | 1 + lib/src/common/byte_buffer.cc | 25 ++ srsue/hdr/stack/rrc/rrc.h | 2 - srsue/test/ttcn3/hdr/ttcn3_helpers.h | 3 +- 9 files changed, 276 insertions(+), 237 deletions(-) create mode 100644 lib/include/srslte/common/byte_buffer.h create mode 100644 lib/src/common/byte_buffer.cc diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index ccecd9c97..d3e83acb0 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -13,6 +13,7 @@ #ifndef SRSLTE_BUFFER_POOL_H #define SRSLTE_BUFFER_POOL_H +#include "byte_buffer.h" #include #include #include @@ -214,13 +215,6 @@ private: buffer_pool* pool; }; -inline void byte_buffer_deleter::operator()(byte_buffer_t* buf) const -{ - if (buf) { - pool->deallocate(buf); - } -} - inline unique_byte_buffer_t allocate_unique_buffer(byte_buffer_pool& pool, bool blocking = false) { return unique_byte_buffer_t(pool.allocate(nullptr, blocking), byte_buffer_deleter(&pool)); diff --git a/lib/include/srslte/common/byte_buffer.h b/lib/include/srslte/common/byte_buffer.h new file mode 100644 index 000000000..c997b83a9 --- /dev/null +++ b/lib/include/srslte/common/byte_buffer.h @@ -0,0 +1,246 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSLTE_BYTE_BUFFER_H +#define SRSLTE_BYTE_BUFFER_H + +#include "common.h" +#include +#include + +//#define SRSLTE_BUFFER_POOL_LOG_ENABLED + +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED +#define pool_allocate (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__)) +#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__, true)) +#define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 +#else +#define pool_allocate (srslte::allocate_unique_buffer(*pool)) +#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, true)) +#endif + +namespace srslte { + +#define ENABLE_TIMESTAMP + +struct buffer_latency_calc { + void clear() + { +#ifdef ENABLE_TIMESTAMP + timestamp_is_set = false; +#endif + } + + std::chrono::microseconds get_latency_us() const + { +#ifdef ENABLE_TIMESTAMP + if (!timestamp_is_set) { + return std::chrono::microseconds{0}; + } + return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - tp); +#else + return std::chrono::microseconds{0}; +#endif + } + + std::chrono::high_resolution_clock::time_point get_timestamp() const { return tp; } + + void set_timestamp() + { +#ifdef ENABLE_TIMESTAMP + tp = std::chrono::high_resolution_clock::now(); + timestamp_is_set = true; +#endif + } + + void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) + { +#ifdef ENABLE_TIMESTAMP + tp = tp_; + timestamp_is_set = true; +#endif + } + +private: +#ifdef ENABLE_TIMESTAMP + std::chrono::high_resolution_clock::time_point tp; + bool timestamp_is_set = false; +#endif +}; + +/****************************************************************************** + * Byte buffer + * + * Generic byte buffer with headroom to accommodate packet headers and custom + * copy constructors & assignment operators for quick copying. Byte buffer + * holds a next pointer to support linked lists. + *****************************************************************************/ +class byte_buffer_t +{ +public: + using iterator = uint8_t*; + using const_iterator = const uint8_t*; + + uint32_t N_bytes; + uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BYTES]; + uint8_t* msg; +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN]; +#endif + + struct buffer_metadata_t { + uint32_t pdcp_sn = 0; + } md; + + byte_buffer_t() : N_bytes(0) + { + bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); +#endif + } + byte_buffer_t(const byte_buffer_t& buf) + { + bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + // copy actual contents + md = buf.md; + N_bytes = buf.N_bytes; + memcpy(msg, buf.msg, N_bytes); + } + byte_buffer_t& operator=(const byte_buffer_t& buf) + { + // avoid self assignment + if (&buf == this) + return *this; + bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bytes = buf.N_bytes; + md = buf.md; + memcpy(msg, buf.msg, N_bytes); + return *this; + } + void clear() + { + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bytes = 0; + md = {}; + tp.clear(); + } + uint32_t get_headroom() { return msg - buffer; } + // Returns the remaining space from what is reported to be the length of msg + uint32_t get_tailroom() { return (sizeof(buffer) - (msg - buffer) - N_bytes); } + std::chrono::microseconds get_latency_us() const { return tp.get_latency_us(); } + + std::chrono::high_resolution_clock::time_point get_timestamp() const { return tp.get_timestamp(); } + + void set_timestamp() { tp.set_timestamp(); } + + void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) { tp.set_timestamp(tp_); } + + void append_bytes(uint8_t* buf, uint32_t size) + { + memcpy(&msg[N_bytes], buf, size); + N_bytes += size; + } + + uint8_t* data() { return msg; } + const uint8_t* data() const { return msg; } + uint32_t size() const { return N_bytes; } + iterator begin() { return msg; } + const iterator begin() const { return msg; } + iterator end() { return msg + N_bytes; } + const_iterator end() const { return msg + N_bytes; } + +private: + buffer_latency_calc tp; +}; + +struct bit_buffer_t { + uint32_t N_bits; + uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BITS]; + uint8_t* msg; +#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED + char debug_name[128]; +#endif + + bit_buffer_t() : N_bits(0) { msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; } + bit_buffer_t(const bit_buffer_t& buf) + { + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bits = buf.N_bits; + memcpy(msg, buf.msg, N_bits); + } + bit_buffer_t& operator=(const bit_buffer_t& buf) + { + // avoid self assignment + if (&buf == this) { + return *this; + } + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bits = buf.N_bits; + memcpy(msg, buf.msg, N_bits); + return *this; + } + void clear() + { + msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; + N_bits = 0; + } + uint32_t get_headroom() { return msg - buffer; } + +private: +}; + +// Create a Managed Life-Time Byte Buffer +class byte_buffer_pool; +class byte_buffer_deleter +{ +public: + explicit byte_buffer_deleter(byte_buffer_pool* pool_ = nullptr) : pool(pool_) {} + void operator()(byte_buffer_t* buf) const; + byte_buffer_pool* pool; +}; + +using unique_byte_buffer_t = std::unique_ptr; + +/// +/// Utilities to create a span out of a byte_buffer. +/// + +using byte_span = span; +using const_byte_span = span; + +inline byte_span make_span(byte_buffer_t& b) +{ + return byte_span{b.msg, b.N_bytes}; +} + +inline const_byte_span make_span(const byte_buffer_t& b) +{ + return const_byte_span{b.msg, b.N_bytes}; +} + +inline byte_span make_span(unique_byte_buffer_t& b) +{ + return byte_span{b->msg, b->N_bytes}; +} + +inline const_byte_span make_span(const unique_byte_buffer_t& b) +{ + return const_byte_span{b->msg, b->N_bytes}; +} + +} // namespace srslte + +#endif // SRSLTE_BYTE_BUFFER_H diff --git a/lib/include/srslte/common/common.h b/lib/include/srslte/common/common.h index b7cd3c424..9937a0f7a 100644 --- a/lib/include/srslte/common/common.h +++ b/lib/include/srslte/common/common.h @@ -65,17 +65,6 @@ #define SRSLTE_MAX_BUFFER_SIZE_BITS (SRSLTE_MAX_TBSIZE_BITS + SRSLTE_BUFFER_HEADER_OFFSET) #define SRSLTE_MAX_BUFFER_SIZE_BYTES (SRSLTE_MAX_TBSIZE_BITS / 8 + SRSLTE_BUFFER_HEADER_OFFSET) -//#define SRSLTE_BUFFER_POOL_LOG_ENABLED - -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED -#define pool_allocate (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__)) -#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, __PRETTY_FUNCTION__, true)) -#define SRSLTE_BUFFER_POOL_LOG_NAME_LEN 128 -#else -#define pool_allocate (srslte::allocate_unique_buffer(*pool)) -#define pool_allocate_blocking (srslte::allocate_unique_buffer(*pool, true)) -#endif - /******************************************************************************* TYPEDEFS *******************************************************************************/ @@ -84,220 +73,6 @@ namespace srslte { #define ENABLE_TIMESTAMP -/****************************************************************************** - * Byte and Bit buffers - * - * Generic buffers with headroom to accommodate packet headers and custom - * copy constructors & assignment operators for quick copying. Byte buffer - * holds a next pointer to support linked lists. - *****************************************************************************/ -class byte_buffer_t -{ -public: - uint32_t N_bytes; - uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BYTES]; - uint8_t* msg; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - char debug_name[SRSLTE_BUFFER_POOL_LOG_NAME_LEN]; -#endif - - struct buffer_metadata_t { - uint32_t pdcp_sn; - } md; - - byte_buffer_t() : N_bytes(0) - { - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; - md = {}; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - bzero(debug_name, SRSLTE_BUFFER_POOL_LOG_NAME_LEN); -#endif - } - byte_buffer_t(const byte_buffer_t& buf) - { - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; - // copy actual contents - md = buf.md; - N_bytes = buf.N_bytes; - memcpy(msg, buf.msg, N_bytes); - } - byte_buffer_t& operator=(const byte_buffer_t& buf) - { - // avoid self assignment - if (&buf == this) - return *this; - bzero(buffer, SRSLTE_MAX_BUFFER_SIZE_BYTES); - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - next = NULL; - N_bytes = buf.N_bytes; - md = buf.md; - memcpy(msg, buf.msg, N_bytes); - return *this; - } - void clear() - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bytes = 0; - md = {}; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - uint32_t get_headroom() { return msg - buffer; } - // Returns the remaining space from what is reported to be the length of msg - uint32_t get_tailroom() { return (sizeof(buffer) - (msg - buffer) - N_bytes); } - std::chrono::microseconds get_latency_us() - { -#ifdef ENABLE_TIMESTAMP - if (!timestamp_is_set) { - return std::chrono::microseconds{0}; - } - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - tp); -#else - return std::chrono::microseconds{0}; -#endif - } - - std::chrono::high_resolution_clock::time_point get_timestamp() { return tp; } - - void set_timestamp() - { -#ifdef ENABLE_TIMESTAMP - tp = std::chrono::high_resolution_clock::now(); - timestamp_is_set = true; -#endif - } - - void set_timestamp(std::chrono::high_resolution_clock::time_point tp_) - { - tp = tp_; - timestamp_is_set = true; - } - - void append_bytes(uint8_t* buf, uint32_t size) - { - memcpy(&msg[N_bytes], buf, size); - N_bytes += size; - } - -private: -#ifdef ENABLE_TIMESTAMP - std::chrono::high_resolution_clock::time_point tp; - bool timestamp_is_set = false; -#endif - byte_buffer_t* next; -}; - -struct bit_buffer_t { - uint32_t N_bits; - uint8_t buffer[SRSLTE_MAX_BUFFER_SIZE_BITS]; - uint8_t* msg; -#ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED - char debug_name[128]; -#endif - - bit_buffer_t() : N_bits(0) - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - bit_buffer_t(const bit_buffer_t& buf) - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = buf.N_bits; - memcpy(msg, buf.msg, N_bits); - } - bit_buffer_t& operator=(const bit_buffer_t& buf) - { - // avoid self assignment - if (&buf == this) { - return *this; - } - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = buf.N_bits; - memcpy(msg, buf.msg, N_bits); - return *this; - } - void clear() - { - msg = &buffer[SRSLTE_BUFFER_HEADER_OFFSET]; - N_bits = 0; -#ifdef ENABLE_TIMESTAMP - timestamp_is_set = false; -#endif - } - uint32_t get_headroom() { return msg - buffer; } - long get_latency_us() - { -#ifdef ENABLE_TIMESTAMP - if (!timestamp_is_set) - return 0; - gettimeofday(×tamp[2], NULL); - return timestamp[0].tv_usec; -#else - return 0; -#endif - } - void set_timestamp() - { -#ifdef ENABLE_TIMESTAMP - gettimeofday(×tamp[1], NULL); - timestamp_is_set = true; -#endif - } - -private: -#ifdef ENABLE_TIMESTAMP - struct timeval timestamp[3]; - bool timestamp_is_set; -#endif -}; - -// Create a Managed Life-Time Byte Buffer -class byte_buffer_pool; -class byte_buffer_deleter -{ -public: - explicit byte_buffer_deleter(byte_buffer_pool* pool_ = nullptr) : pool(pool_) {} - void operator()(byte_buffer_t* buf) const; - byte_buffer_pool* pool; -}; - -typedef std::unique_ptr unique_byte_buffer_t; - -/// -/// Utilities to create a span out of a byte_buffer. -/// - -using byte_span = span; -using const_byte_span = span; - -inline byte_span make_span(byte_buffer_t& b) -{ - return byte_span{b.msg, b.N_bytes}; -} - -inline const_byte_span make_span(const byte_buffer_t& b) -{ - return const_byte_span{b.msg, b.N_bytes}; -} - -inline byte_span make_span(unique_byte_buffer_t& b) -{ - return byte_span{b->msg, b->N_bytes}; -} - -inline const_byte_span make_span(const unique_byte_buffer_t& b) -{ - return const_byte_span{b->msg, b->N_bytes}; -} - // helper functions inline const char* enum_to_text(const char* const array[], uint32_t nof_types, uint32_t enum_val) { diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index c515afb07..c502d56b6 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -13,6 +13,7 @@ #ifndef SRSLTE_INTERFACES_COMMON_H #define SRSLTE_INTERFACES_COMMON_H +#include "srslte/common/byte_buffer.h" #include "srslte/common/security.h" #include "srslte/phy/common/phy_common.h" #include diff --git a/lib/src/asn1/gtpc.cc b/lib/src/asn1/gtpc.cc index 991500c1f..031d34bc9 100644 --- a/lib/src/asn1/gtpc.cc +++ b/lib/src/asn1/gtpc.cc @@ -10,7 +10,7 @@ * */ #include "srslte/asn1/gtpc.h" -#include "srslte/common/common.h" +#include "srslte/common/byte_buffer.h" #include namespace srslte { diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index 6bb7c17d3..a2ea81698 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -10,6 +10,7 @@ set(SOURCES arch_select.cc enb_events.cc backtrace.c + byte_buffer.cc band_helper.cc buffer_pool.cc crash_handler.cc diff --git a/lib/src/common/byte_buffer.cc b/lib/src/common/byte_buffer.cc new file mode 100644 index 000000000..4b5af8e17 --- /dev/null +++ b/lib/src/common/byte_buffer.cc @@ -0,0 +1,25 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2020 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srslte/common/byte_buffer.h" +#include "srslte/common/buffer_pool.h" + +namespace srslte { + +void byte_buffer_deleter::operator()(byte_buffer_t* buf) const +{ + if (buf) { + pool->deallocate(buf); + } +} + +} // namespace srslte \ No newline at end of file diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 0c0006612..93cafacf5 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -192,8 +192,6 @@ private: void send_ul_ccch_msg(const asn1::rrc::ul_ccch_msg_s& msg); void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc::ul_dcch_msg_s& msg); - srslte::bit_buffer_t bit_buf; - rrc_state_t state = RRC_STATE_IDLE, last_state = RRC_STATE_IDLE; uint8_t transaction_id = 0; srslte::s_tmsi_t ue_identity; diff --git a/srsue/test/ttcn3/hdr/ttcn3_helpers.h b/srsue/test/ttcn3/hdr/ttcn3_helpers.h index bf398c402..ab9d4c2b0 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_helpers.h +++ b/srsue/test/ttcn3/hdr/ttcn3_helpers.h @@ -21,7 +21,7 @@ #include "rapidjson/document.h" // rapidjson's DOM-style API #include "rapidjson/prettywriter.h" // for stringify JSON #include "srslte/asn1/asn1_utils.h" -#include "srslte/common/common.h" +#include "srslte/common/byte_buffer.h" #include #include #include @@ -381,7 +381,6 @@ public: document["Common"]["TimingInfo"].HasMember("SubFrame") && document["Common"]["TimingInfo"]["SubFrame"].HasMember("SFN") && document["Common"]["TimingInfo"]["SubFrame"]["SFN"].HasMember("Number")) { - timing.tti = document["Common"]["TimingInfo"]["SubFrame"]["SFN"]["Number"].GetInt() * 10; // check SF index only