From d8e9705bc6c34b8d015b56a76955ee2f15426bd8 Mon Sep 17 00:00:00 2001 From: Alex Williams Date: Mon, 8 Jul 2019 16:44:15 -0700 Subject: rfnoc: Add tracking of 'valid' bit to properties The valid bit helps prevent placeholder defaults from being propagated through the graph. Values that are not valid will not be forwarded. --- host/include/uhd/rfnoc/dirtifier.hpp | 22 ++++++++++++++--- host/include/uhd/rfnoc/property.hpp | 47 ++++++++++++++++++++++++++++++------ host/include/uhd/rfnoc/property.ipp | 22 +++++++++++++---- 3 files changed, 74 insertions(+), 17 deletions(-) (limited to 'host/include') 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 #include #include -#include #include +#include 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& 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 clone(res_source_info new_src_info) override { - return std::unique_ptr(new property_t( - get_id(), get(), new_src_info)); + return std::unique_ptr( + new property_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* prop_ptr = dynamic_cast*>(next_prop); if (prop_ptr == nullptr) { throw uhd::type_error(std::string("Unable to cast property ") @@ -247,6 +278,7 @@ private: } dirty_tracked _data; + bool _valid; }; // class property_t }} /* namespace uhd::rfnoc */ @@ -254,4 +286,3 @@ private: #include #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 -uhd::rfnoc::property_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)) +uhd::rfnoc::property_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)) + , _valid(true) { // nop } template -uhd::rfnoc::property_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::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 +uhd::rfnoc::property_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 */ -- cgit v1.2.3