diff options
Diffstat (limited to 'host')
-rw-r--r-- | host/include/uhd/rfnoc/dirtifier.hpp | 22 | ||||
-rw-r--r-- | host/include/uhd/rfnoc/property.hpp | 47 | ||||
-rw-r--r-- | host/include/uhd/rfnoc/property.ipp | 22 | ||||
-rw-r--r-- | host/lib/include/uhdlib/rfnoc/prop_accessor.hpp | 2 | ||||
-rw-r--r-- | host/lib/rfnoc/node.cpp | 9 |
5 files changed, 84 insertions, 18 deletions
diff --git a/host/include/uhd/rfnoc/dirtifier.hpp b/host/include/uhd/rfnoc/dirtifier.hpp index cc4430d3d..e31b26595 100644 --- a/host/include/uhd/rfnoc/dirtifier.hpp +++ b/host/include/uhd/rfnoc/dirtifier.hpp @@ -26,10 +26,22 @@ public: } //! This property is always dirty - bool is_dirty() const { return true; } + bool is_dirty() const + { + return true; + } + + //! This property is always invalid + bool is_valid() const + { + return false; + } //! This property is never equal to anything else - bool equal(property_base_t*) const { return false; } + bool equal(property_base_t*) const + { + return false; + } //! Always dirty, so this can be called as often as we like void force_dirty() {} @@ -45,10 +57,12 @@ private: } //! This property never has the same type as another type - bool is_type_equal(property_base_t*) const { return false; } + bool is_type_equal(property_base_t*) const + { + return false; + } }; }} /* namespace uhd::rfnoc */ #endif /* INCLUDED_LIBUHD_DIRTIFYIER_HPP */ - diff --git a/host/include/uhd/rfnoc/property.hpp b/host/include/uhd/rfnoc/property.hpp index a85c978e9..d01613c58 100644 --- a/host/include/uhd/rfnoc/property.hpp +++ b/host/include/uhd/rfnoc/property.hpp @@ -10,8 +10,8 @@ #include <uhd/exception.hpp> #include <uhd/rfnoc/res_source_info.hpp> #include <uhd/utils/dirty_tracked.hpp> -#include <string> #include <memory> +#include <string> namespace uhd { namespace rfnoc { @@ -27,9 +27,10 @@ class UHD_API property_base_t public: enum access_t { NONE, //!< Neither reading nor writing to this property is permitted - RO = 0x1, //!< Read-Only - RW = 0x3, //!< Read-Write - RWLOCKED = 0x5 //!< Write is locked. This lets you call set(), but only if the value is unchanged. + RO = 0x1, //!< Read-Only + RW = 0x3, //!< Read-Write + RWLOCKED = 0x5 //!< Write is locked. This lets you call set(), but only if the + //!< value is unchanged. }; property_base_t(const std::string& id, const res_source_info& source_info) @@ -55,6 +56,12 @@ public: // have not propagated yet and still need resolving. virtual bool is_dirty() const = 0; + //! Query this property's valid flag. + // + // If it's false, that means this property has a default value that should + // NOT be forwarded. + virtual bool is_valid() const = 0; + //! Returns true if this property can be read. bool read_access_granted() const { @@ -132,6 +139,8 @@ public: property_t( const std::string& id, const data_t& value, const res_source_info& source_info); + property_t(const std::string& id, const res_source_info& source_info); + property_t(const property_t<data_t>& prop) = default; //! Returns the dirty state of this property @@ -143,6 +152,15 @@ public: return _data.is_dirty(); } + //! Query this property's valid flag. + // + // If it's false, that means this property has a default value that should + // NOT be used. + bool is_valid() const + { + return _valid; + } + bool equal(property_base_t* rhs) const { if (!is_type_equal(rhs)) { @@ -153,8 +171,8 @@ public: std::unique_ptr<property_base_t> clone(res_source_info new_src_info) override { - return std::unique_ptr<property_base_t>(new property_t<data_t>( - get_id(), get(), new_src_info)); + return std::unique_ptr<property_base_t>( + new property_t<data_t>(get_id(), get(), new_src_info)); } //! Returns the source info for the property @@ -168,7 +186,8 @@ public: void set(const data_t& value) { if (write_access_granted()) { - _data = value; + _data = value; + _valid = true; } else if (get_access_mode() == RWLOCKED) { if (_data.get() != value) { throw uhd::resolve_error(std::string("Attempting to overwrite property `") @@ -198,8 +217,16 @@ public: } //! Get the value of this property + // + // \throws uhd::access_error if either the property is flagged as invalid, + // or if no read access was granted. const data_t& get() const { + if (!is_valid()) { + throw uhd::access_error(std::string("Attempting to read property `") + + get_id() + "@" + get_src_info().to_string() + + "' before it was initialized!"); + } if (read_access_granted()) { return _data; } @@ -231,6 +258,10 @@ private: void forward(property_base_t* next_prop) { + if (not _valid) { + throw uhd::resolve_error( + std::string("Unable to forward invalid property ") + get_id()); + } property_t<data_t>* prop_ptr = dynamic_cast<property_t<data_t>*>(next_prop); if (prop_ptr == nullptr) { throw uhd::type_error(std::string("Unable to cast property ") @@ -247,6 +278,7 @@ private: } dirty_tracked<data_t> _data; + bool _valid; }; // class property_t }} /* namespace uhd::rfnoc */ @@ -254,4 +286,3 @@ private: #include <uhd/rfnoc/property.ipp> #endif /* INCLUDED_LIBUHD_PROPERTY_HPP */ - diff --git a/host/include/uhd/rfnoc/property.ipp b/host/include/uhd/rfnoc/property.ipp index 101aa5d7e..87b4394e6 100644 --- a/host/include/uhd/rfnoc/property.ipp +++ b/host/include/uhd/rfnoc/property.ipp @@ -8,18 +8,30 @@ #define INCLUDED_LIBUHD_PROPERTY_IPP template <typename data_t> -uhd::rfnoc::property_t<data_t>::property_t(const std::string& id, data_t&& data, const uhd::rfnoc::res_source_info& source_info) - : uhd::rfnoc::property_base_t(id, source_info), _data(std::forward<data_t>(data)) +uhd::rfnoc::property_t<data_t>::property_t( + const std::string& id, data_t&& data, const uhd::rfnoc::res_source_info& source_info) + : uhd::rfnoc::property_base_t(id, source_info) + , _data(std::forward<data_t>(data)) + , _valid(true) { // nop } template <typename data_t> -uhd::rfnoc::property_t<data_t>::property_t(const std::string& id, const data_t& data, const uhd::rfnoc::res_source_info& source_info) - : uhd::rfnoc::property_base_t(id, source_info), _data(data) +uhd::rfnoc::property_t<data_t>::property_t(const std::string& id, + const data_t& data, + const uhd::rfnoc::res_source_info& source_info) + : uhd::rfnoc::property_base_t(id, source_info), _data(data), _valid(true) { // nop } -#endif /* INCLUDED_LIBUHD_PROPERTY_IPP */ +template <typename data_t> +uhd::rfnoc::property_t<data_t>::property_t( + const std::string& id, const uhd::rfnoc::res_source_info& source_info) + : uhd::rfnoc::property_base_t(id, source_info), _valid(false) +{ + // nop +} +#endif /* INCLUDED_LIBUHD_PROPERTY_IPP */ diff --git a/host/lib/include/uhdlib/rfnoc/prop_accessor.hpp b/host/lib/include/uhdlib/rfnoc/prop_accessor.hpp index a62f54620..2f39cbbec 100644 --- a/host/lib/include/uhdlib/rfnoc/prop_accessor.hpp +++ b/host/lib/include/uhdlib/rfnoc/prop_accessor.hpp @@ -65,7 +65,7 @@ public: * * Note: This method will grant temporary write access to the destination * property! - * If \p safe is set to true, it'll only allow RWLOCKED forwarding, i.e., + * If \p safe is set to true, it'll only allow RWLOCKED forwarding, i.e., * the new value cannot be different. * * \throws uhd::type_error if types mismatch diff --git a/host/lib/rfnoc/node.cpp b/host/lib/rfnoc/node.cpp index b3ad2b380..cdb69e158 100644 --- a/host/lib/rfnoc/node.cpp +++ b/host/lib/rfnoc/node.cpp @@ -444,6 +444,15 @@ void node_t::forward_edge_property( "Incoming edge property: `" << incoming_prop->get_id() << "`, source info: " << incoming_prop->get_src_info().to_string()); + // Don't forward properties that are not yet valid + if (!incoming_prop->is_valid()) { + UHD_LOG_TRACE(get_unique_id(), + "Skipped empty edge property: `" + << incoming_prop->get_id() + << "`, source info: " << incoming_prop->get_src_info().to_string()); + return; + } + // The source type of my local prop (it's the opposite of the source type // of incoming_prop) const auto prop_src_type = |