diff options
| author | Ashish Chaudhari <ashish@ettus.com> | 2015-08-10 22:23:59 -0700 | 
|---|---|---|
| committer | Ashish Chaudhari <ashish@ettus.com> | 2015-08-10 22:23:59 -0700 | 
| commit | 16e149fe6fcc1bc18adea3eeeefad2c7ee93b2e0 (patch) | |
| tree | 93e1dbdb3818fb6fdce047cb779fb2b28979a2c1 | |
| parent | e28a050d42ba19e4c6200fb20ec7f1ec064c9567 (diff) | |
| download | uhd-16e149fe6fcc1bc18adea3eeeefad2c7ee93b2e0.tar.gz uhd-16e149fe6fcc1bc18adea3eeeefad2c7ee93b2e0.tar.bz2 uhd-16e149fe6fcc1bc18adea3eeeefad2c7ee93b2e0.zip  | |
uhd: Added dirty tracking support to soft_register
| -rw-r--r-- | host/include/uhd/utils/soft_register.hpp | 55 | 
1 files changed, 38 insertions, 17 deletions
diff --git a/host/include/uhd/utils/soft_register.hpp b/host/include/uhd/utils/soft_register.hpp index 9c407cd74..63dccf06a 100644 --- a/host/include/uhd/utils/soft_register.hpp +++ b/host/include/uhd/utils/soft_register.hpp @@ -22,6 +22,7 @@  #include <boost/noncopyable.hpp>  #include <uhd/types/wb_iface.hpp>  #include <uhd/exception.hpp> +#include <uhd/utils/dirty_tracked.hpp>  #include <boost/thread/mutex.hpp>  #include <boost/thread/locks.hpp>  #include <boost/unordered_map.hpp> @@ -115,6 +116,8 @@ public:      }  }; +enum soft_reg_flush_mode_t { OPTIMIZED_FLUSH, ALWAYS_FLUSH }; +  /*!   * Soft register object that holds offset, soft-copy and the control iface.   * Methods give convenient field-level access to soft-copy and the ability @@ -131,16 +134,21 @@ public:      /*!       * Generic constructor for all soft_register types       */ -    soft_register_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr): -        _iface(NULL), _wr_addr(wr_addr), _rd_addr(rd_addr), _soft_copy(0) +    explicit soft_register_t( +            wb_iface::wb_addr_type wr_addr, +            wb_iface::wb_addr_type rd_addr, +            soft_reg_flush_mode_t mode = ALWAYS_FLUSH): +        _iface(NULL), _wr_addr(wr_addr), _rd_addr(rd_addr), _soft_copy(0), _flush_mode(mode)      {}      /*!       * Constructor for read-only, write-only registers and read-write registers       * with rd_addr == wr_addr       */ -    soft_register_t(wb_iface::wb_addr_type addr): -        _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0) +    explicit soft_register_t( +            wb_iface::wb_addr_type addr, +            soft_reg_flush_mode_t mode = ALWAYS_FLUSH): +        _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0), _flush_mode(mode)      {}      /*! @@ -183,14 +191,20 @@ public:      inline void flush()      {          if (writable && _iface) { -            if (get_bitwidth() <= 16) { -                _iface->poke16(_wr_addr, static_cast<boost::uint16_t>(_soft_copy)); -            } else if (get_bitwidth() <= 32) { -                _iface->poke32(_wr_addr, static_cast<boost::uint32_t>(_soft_copy)); -            } else if (get_bitwidth() <= 64) { -                _iface->poke64(_wr_addr, static_cast<boost::uint64_t>(_soft_copy)); -            } else { -                throw uhd::not_implemented_error("soft_register only supports up to 64 bits."); +            //If optimized flush then poke only if soft copy is dirty +            //If flush mode is ALWAYS, the dirty flag should get optimized +            //out by the compiler because it is never read +            if (_flush_mode == ALWAYS_FLUSH || _soft_copy.is_dirty()) { +                if (get_bitwidth() <= 16) { +                    _iface->poke16(_wr_addr, static_cast<boost::uint16_t>(_soft_copy)); +                } else if (get_bitwidth() <= 32) { +                    _iface->poke32(_wr_addr, static_cast<boost::uint32_t>(_soft_copy)); +                } else if (get_bitwidth() <= 64) { +                    _iface->poke64(_wr_addr, static_cast<boost::uint64_t>(_soft_copy)); +                } else { +                    throw uhd::not_implemented_error("soft_register only supports up to 64 bits."); +                } +                _soft_copy.mark_clean();              }          } else {              throw uhd::not_implemented_error("soft_register is not writable."); @@ -212,6 +226,7 @@ public:              } else {                  throw uhd::not_implemented_error("soft_register only supports up to 64 bits.");              } +            _soft_copy.mark_clean();          } else {              throw uhd::not_implemented_error("soft_register is not readable.");          } @@ -264,7 +279,8 @@ private:      wb_iface*                       _iface;      const wb_iface::wb_addr_type    _wr_addr;      const wb_iface::wb_addr_type    _rd_addr; -    reg_data_t                      _soft_copy; +    dirty_tracked<reg_data_t>       _soft_copy; +    const soft_reg_flush_mode_t     _flush_mode;  };  /*! @@ -276,12 +292,17 @@ class UHD_API soft_register_sync_t : public soft_register_t<reg_data_t, readable  public:      typedef boost::shared_ptr< soft_register_sync_t<reg_data_t, readable, writable> > sptr; -    soft_register_sync_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr): -        soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr), _mutex() +    explicit soft_register_sync_t( +            wb_iface::wb_addr_type wr_addr, +            wb_iface::wb_addr_type rd_addr, +            soft_reg_flush_mode_t mode = ALWAYS_FLUSH): +        soft_register_t<reg_data_t, readable, writable>(wr_addr, rd_addr, mode), _mutex()      {} -    soft_register_sync_t(wb_iface::wb_addr_type addr): -        soft_register_t<reg_data_t, readable, writable>(addr), _mutex() +    explicit soft_register_sync_t( +            wb_iface::wb_addr_type addr, +            soft_reg_flush_mode_t mode = ALWAYS_FLUSH): +        soft_register_t<reg_data_t, readable, writable>(addr, mode), _mutex()      {}      inline void initialize(wb_iface& iface, bool sync = false)  | 
