diff --git a/lib/include/srsran/adt/adt_utils.h b/lib/include/srsran/adt/adt_utils.h deleted file mode 100644 index 98b816d77..000000000 --- a/lib/include/srsran/adt/adt_utils.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 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 SRSRAN_ADT_UTILS_H -#define SRSRAN_ADT_UTILS_H - -#ifdef __EXCEPTIONS - -#include - -#define EXCEPTIONS_ENABLED 1 - -namespace srsran { - -class bad_type_access : public std::runtime_error -{ -public: - explicit bad_type_access(const std::string& what_arg) : runtime_error(what_arg) {} - explicit bad_type_access(const char* what_arg) : runtime_error(what_arg) {} -}; - -#define THROW_BAD_ACCESS(msg) throw bad_type_access(msg) - -} // namespace srsran - -#else - -#define EXCEPTIONS_ENABLED 0 - -#include -#include - -namespace srsran { - -#define THROW_BAD_ACCESS(msg) \ - std::fprintf(stderr, "ERROR: exception thrown with %s", msg); \ - std::abort() - -} // namespace srsran - -#endif - -#endif // SRSRAN_ADT_UTILS_H diff --git a/lib/include/srsran/adt/bounded_bitset.h b/lib/include/srsran/adt/bounded_bitset.h index ed86c23d8..22d656668 100644 --- a/lib/include/srsran/adt/bounded_bitset.h +++ b/lib/include/srsran/adt/bounded_bitset.h @@ -13,7 +13,7 @@ #ifndef SRSRAN_DYN_BITSET_H #define SRSRAN_DYN_BITSET_H -#include "adt_utils.h" +#include "srsran/common/srsran_assert.h" #include "srsran/srslog/bundled/fmt/format.h" #include #include @@ -43,11 +43,7 @@ public: void resize(size_t new_size) { - if (new_size > max_size()) { - std::string msg = - "ERROR: new size=" + std::to_string(new_size) + " exceeds bitset capacity=" + std::to_string(max_size()); - THROW_BAD_ACCESS(msg.c_str()); - } + srsran_assert(new_size <= max_size(), "ERROR: new size=%zd exceeds bitset capacity=%zd", new_size, max_size()); if (new_size == cur_size) { return; } @@ -191,11 +187,10 @@ public: bounded_bitset& operator|=(const bounded_bitset& other) { - if (other.size() != size()) { - std::string msg = "operator|= called for bitsets of different sizes (" + std::to_string(size()) + - "!=" + std::to_string(other.size()) + ")"; - THROW_BAD_ACCESS(msg.c_str()); - } + srsran_assert(other.size() == size(), + "ERROR: operator|= called for bitsets of different sizes (%zd!=%zd)", + size(), + other.size()); for (size_t i = 0; i < nof_words_(); ++i) { buffer[i] |= other.buffer[i]; } @@ -204,11 +199,10 @@ public: bounded_bitset& operator&=(const bounded_bitset& other) { - if (other.size() != size()) { - std::string msg = "operator&= called for bitsets of different sizes (" + std::to_string(size()) + - "!=" + std::to_string(other.size()) + ")"; - THROW_BAD_ACCESS(msg.c_str()); - } + srsran_assert(other.size() == size(), + "ERROR: operator&= called for bitsets of different sizes (%zd!=%zd)", + size(), + other.size()); for (size_t i = 0; i < nof_words_(); ++i) { buffer[i] &= other.buffer[i]; } @@ -245,10 +239,7 @@ public: uint64_t to_uint64() const { - if (nof_words_() > 1) { - std::string msg = "ERROR: cannot convert bitset of size=" + std::to_string(size()) + " to uint64_t"; - THROW_BAD_ACCESS(msg.c_str()); - } + srsran_assert(nof_words_() == 1, "ERROR: cannot convert bitset of size=%zd to uint64_t", size()); return get_word_(0); } @@ -310,11 +301,10 @@ private: void assert_within_bounds_(size_t pos, bool strict) const { - if (pos > size() or (strict and pos == size())) { - std::string msg = - "ERROR: index=" + std::to_string(pos) + "is out of bounds for bitset of size=" + std::to_string(size()); - THROW_BAD_ACCESS(msg.c_str()); - } + srsran_assert(pos < size() or (not strict and pos == size()), + "ERROR: index=%zd is out-of-bounds for bitset of size=%zd", + pos, + size()); } static word_t maskbit(size_t pos) { return (static_cast(1)) << (pos % bits_per_word); } diff --git a/lib/include/srsran/adt/bounded_vector.h b/lib/include/srsran/adt/bounded_vector.h index 239c975af..becf2db74 100644 --- a/lib/include/srsran/adt/bounded_vector.h +++ b/lib/include/srsran/adt/bounded_vector.h @@ -13,6 +13,7 @@ #ifndef SRSRAN_BOUNDED_VECTOR_H #define SRSRAN_BOUNDED_VECTOR_H +#include "srsran/adt/detail/type_storage.h" #include "srsran/common/srsran_assert.h" #include #include @@ -88,12 +89,12 @@ public: T& operator[](std::size_t i) { srsran_assert(i < size_, "Array index is out of bounds."); - return reinterpret_cast(buffer[i]); + return buffer[i].get(); } const T& operator[](std::size_t i) const { srsran_assert(i < size_, "Array index is out of bounds."); - return reinterpret_cast(buffer[i]); + return buffer[i].get(); } T& back() { @@ -107,8 +108,8 @@ public: } T& front() { return (*this)[0]; } const T& front() const { return (*this)[0]; } - T* data() { return reinterpret_cast(buffer); } - const T* data() const { return reinterpret_cast(buffer); } + T* data() { return &buffer[0].get(); } + const T* data() const { return &buffer[0].get(); } // Iterators iterator begin() { return data(); } @@ -226,13 +227,13 @@ private: static_assert(std::is_default_constructible::value, "T must be default-constructible"); 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(); + buffer[i].emplace(); } size_ += N; } - std::size_t size_ = 0; - typename std::aligned_storage::type buffer[MAX_N]; + std::size_t size_ = 0; + std::array, MAX_N> buffer; }; } // namespace srsran diff --git a/lib/include/srsran/adt/detail/index_sequence.h b/lib/include/srsran/adt/detail/index_sequence.h index 241d4e8c2..d3022ab2f 100644 --- a/lib/include/srsran/adt/detail/index_sequence.h +++ b/lib/include/srsran/adt/detail/index_sequence.h @@ -13,6 +13,8 @@ #ifndef CPP_TESTS_INDEX_SEQUENCE_H #define CPP_TESTS_INDEX_SEQUENCE_H +#include + namespace srsran { template diff --git a/lib/include/srsran/adt/detail/type_utils.h b/lib/include/srsran/adt/detail/type_utils.h index 6a42f966a..0aa9a61c9 100644 --- a/lib/include/srsran/adt/detail/type_utils.h +++ b/lib/include/srsran/adt/detail/type_utils.h @@ -271,19 +271,15 @@ const T* get_if(const TypeContainer& c) template T& get(TypeContainer& c) { - if (c.template is()) { - return c.template get_unchecked(); - } - THROW_BAD_ACCESS("in get"); + srsran_assert(c.template is(), "Bad access via get"); + return c.template get_unchecked(); } template const T& get(const TypeContainer& c) { - if (c.template is()) { - return c.template get_unchecked(); - } - THROW_BAD_ACCESS("in get"); + srsran_assert(c.template is(), "Bad access via get"); + return c.template get_unchecked(); } template #include @@ -21,6 +21,14 @@ namespace srsran { struct default_error_t {}; +template +class expected; + +template +struct is_expected : std::false_type {}; +template +struct is_expected > : std::true_type {}; + template class expected { @@ -32,6 +40,12 @@ public: expected(const T& t) : has_val(true), val(t) {} expected(E&& e) : has_val(false), unexpected(std::forward(e)) {} expected(const E& e) : has_val(false), unexpected(e) {} + template < + typename U, + typename std::enable_if::value and not is_expected::type>::value, + int>::type = 0> + explicit expected(U&& u) : has_val(true), val(std::forward(u)) + {} expected(const expected& other) { if (other.has_val) { @@ -105,30 +119,22 @@ public: bool is_error() const { return not has_value(); } const T& value() const { - if (not has_val) { - THROW_BAD_ACCESS("Bad expected value access"); - } + srsran_assert(has_value(), "Bad expected value access"); return val; } T& value() { - if (not has_val) { - THROW_BAD_ACCESS("Bad expected value access"); - } + srsran_assert(has_value(), "Bad expected value access"); return val; } const E& error() const { - if (has_val) { - THROW_BAD_ACCESS("Bad expected error access"); - } + srsran_assert(not has_value(), "Bad expected error access"); return unexpected; } E& error() { - if (has_val) { - THROW_BAD_ACCESS("Bad expected error access"); - } + srsran_assert(not has_value(), "Bad expected error access"); return unexpected; } diff --git a/lib/include/srsran/common/fsm.h b/lib/include/srsran/adt/fsm.h similarity index 98% rename from lib/include/srsran/common/fsm.h rename to lib/include/srsran/adt/fsm.h index 760381640..1e00946d7 100644 --- a/lib/include/srsran/common/fsm.h +++ b/lib/include/srsran/adt/fsm.h @@ -18,8 +18,6 @@ #include "srsran/srslog/srslog.h" #include #include -#include -#include #include #include @@ -36,17 +34,17 @@ namespace srsran { -//! Forward declarations +/// Forward declarations template class base_fsm_t; template class composite_fsm_t; -//! Check if type T is an FSM +/// Check if type T is an FSM template using is_fsm = std::is_base_of, T>; -//! Check if type T is a composite FSM +/// Check if type T is a composite FSM template struct is_composite_fsm : public std::false_type {}; template @@ -259,7 +257,7 @@ struct apply_first_guard_pass > { } }; -//! Trigger Event, that will result in a state transition +/// Trigger Event that may result in a state transition template struct trigger_visitor { using event_t = typename std::decay::type; @@ -679,10 +677,8 @@ public: const Result& get_result() const { - if (launch_counter > 0 and base_t::template is_in_state()) { - return last_result; - } - THROW_BAD_ACCESS("in proc_fsm_t::get_result"); + srsran_assert(launch_counter > 0 and base_t::template is_in_state(), "in proc_fsm_t::get_result"); + return last_result; } template diff --git a/lib/include/srsran/adt/interval.h b/lib/include/srsran/adt/interval.h index 6724b47f9..930e5250e 100644 --- a/lib/include/srsran/adt/interval.h +++ b/lib/include/srsran/adt/interval.h @@ -13,7 +13,7 @@ #ifndef SRSRAN_INTERVAL_H #define SRSRAN_INTERVAL_H -#include "adt_utils.h" +#include "srsran/common/srsran_assert.h" #include "srsran/srslog/bundled/fmt/format.h" #include #include @@ -43,7 +43,7 @@ public: void set(T start_point, T stop_point) { - assert(stop_point >= start_point); + srsran_assert(stop_point >= start_point, "interval::set called for invalid range points"); start_ = start_point; stop_ = stop_point; } @@ -51,13 +51,13 @@ public: void resize_by(T len) { // Detect length overflows - assert(std::is_unsigned::value or (len >= 0 or length() >= -len)); + srsran_assert(std::is_unsigned::value or (len >= 0 or length() >= -len), "Resulting interval would be invalid"); stop_ += len; } void resize_to(T len) { - assert(std::is_unsigned::value or len >= 0); + srsran_assert(std::is_unsigned::value or len >= 0, "Interval width must be positive"); stop_ = start_ + len; } diff --git a/lib/include/srsran/adt/move_callback.h b/lib/include/srsran/adt/move_callback.h index 1ea0129b3..2e2d91422 100644 --- a/lib/include/srsran/adt/move_callback.h +++ b/lib/include/srsran/adt/move_callback.h @@ -13,6 +13,8 @@ #ifndef SRSRAN_MOVE_CALLBACK_H #define SRSRAN_MOVE_CALLBACK_H +#include "detail/type_storage.h" +#include "srsran/common/srsran_assert.h" #include #include #include @@ -25,23 +27,11 @@ #define THROW_BAD_FUNCTION_CALL(const char* cause) throw std::bad_function_call{}; #else #define THROW_BAD_FUNCTION_CALL(cause) \ - fprintf(stderr, "ERROR: exception thrown due to bad function call (cause: %s)\n", cause); \ - std::abort() + srsran_assert(false, "ERROR: exception thrown due to bad function call (cause: %s)\n", cause); #endif namespace srsran { -// NOTE: gcc 4.8.5 is missing std::max_align_t. Need to create a struct -union max_alignment_t { - char c; - float f; - uint32_t i; - uint64_t i2; - double d; - long double d2; - uint32_t* ptr; -}; - //! Size of the buffer used by "move_callback" to store functors without calling "new" constexpr size_t default_buffer_size = 32; @@ -68,10 +58,13 @@ class empty_table_t : public oper_table_t { public: constexpr empty_table_t() = default; - R call(void* src, Args&&... args) const final { THROW_BAD_FUNCTION_CALL("function ptr is empty"); } - void move(void* src, void* dest) const final {} - void dtor(void* src) const final {} - bool is_in_small_buffer() const final { return true; } + R call(void* src, Args&&... args) const final + { + srsran_terminate("ERROR: bad function call (cause: function ptr is empty)"); + } + void move(void* src, void* dest) const final {} + void dtor(void* src) const final {} + bool is_in_small_buffer() const final { return true; } }; //! specialization of move/call/destroy operations for when the functor is stored in "move_callback" buffer @@ -126,7 +119,7 @@ template class move_callback { static constexpr size_t capacity = Capacity >= sizeof(void*) ? Capacity : sizeof(void*); ///< size of buffer - using storage_t = typename std::aligned_storage::type; + using storage_t = typename std::aligned_storage::type; using oper_table_t = task_details::oper_table_t; static constexpr task_details::empty_table_t empty_table{}; diff --git a/lib/include/srsran/common/srsran_assert.h b/lib/include/srsran/common/srsran_assert.h index 77094ac0f..d4da8267f 100644 --- a/lib/include/srsran/common/srsran_assert.h +++ b/lib/include/srsran/common/srsran_assert.h @@ -16,10 +16,14 @@ #include "srsran/srslog/srslog.h" #include -#ifdef ASSERTS_ENABLED - #define srsran_unlikely(expr) __builtin_expect(!!(expr), 0) +#define srsran_terminate(fmt, ...) \ + std::fprintf(stderr, "%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ + std::abort() + +#ifdef ASSERTS_ENABLED + /** * Macro that asserts condition is true. If false, it logs the remaining parameters, prints the backtrace and closes * the application @@ -27,8 +31,7 @@ #define srsran_assert(condition, fmt, ...) \ do { \ if (srsran_unlikely(not(condition))) { \ - std::fprintf(stderr, "%s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__); \ - std::abort(); \ + srsran_terminate(fmt, ##__VA_ARGS__); \ } \ } while (0) diff --git a/lib/test/adt/CMakeLists.txt b/lib/test/adt/CMakeLists.txt index 983a7959f..c95661231 100644 --- a/lib/test/adt/CMakeLists.txt +++ b/lib/test/adt/CMakeLists.txt @@ -49,3 +49,7 @@ add_test(circular_buffer_test circular_buffer_test) add_executable(circular_map_test circular_map_test.cc) target_link_libraries(circular_map_test srsran_common) add_test(circular_map_test circular_map_test) + +add_executable(fsm_test fsm_test.cc) +target_link_libraries(fsm_test srsran_common) +add_test(fsm_test fsm_test) diff --git a/lib/test/common/fsm_test.cc b/lib/test/adt/fsm_test.cc similarity index 99% rename from lib/test/common/fsm_test.cc rename to lib/test/adt/fsm_test.cc index e407ee402..edf41eb83 100644 --- a/lib/test/common/fsm_test.cc +++ b/lib/test/adt/fsm_test.cc @@ -10,7 +10,7 @@ * */ -#include "srsran/common/fsm.h" +#include "srsran/adt/fsm.h" #include "srsran/common/test_common.h" ///////////////////////////// diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index e8ae1c280..adf5eeb34 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -64,10 +64,6 @@ add_executable(tti_point_test tti_point_test.cc) target_link_libraries(tti_point_test srsran_common) add_test(tti_point_test tti_point_test) -add_executable(fsm_test fsm_test.cc) -target_link_libraries(fsm_test srsran_common) -add_test(fsm_test fsm_test) - add_executable(choice_type_test choice_type_test.cc) target_link_libraries(choice_type_test srsran_common) add_test(choice_type_test choice_type_test) diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 8656f3386..e18976a03 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -15,7 +15,7 @@ #include "rrc.h" #include "rrc_ue.h" -#include "srsran/common/fsm.h" +#include "srsran/adt/fsm.h" #include namespace srsenb { diff --git a/srsue/hdr/stack/rrc/phy_controller.h b/srsue/hdr/stack/rrc/phy_controller.h index 742bee6ba..481dcc626 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -13,8 +13,8 @@ #ifndef SRSRAN_PHY_CONTROLLER_H #define SRSRAN_PHY_CONTROLLER_H +#include "srsran/adt/fsm.h" #include "srsran/adt/observer.h" -#include "srsran/common/fsm.h" #include "srsran/common/task_scheduler.h" #include "srsran/interfaces/ue_phy_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h"