diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/include/uhdlib/rfnoc/chdr_types.hpp | 6 | ||||
| -rw-r--r-- | host/lib/rfnoc/ctrlport_endpoint.cpp | 30 | 
2 files changed, 31 insertions, 5 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp index b5725710b..8bb345b32 100644 --- a/host/lib/include/uhdlib/rfnoc/chdr_types.hpp +++ b/host/lib/include/uhdlib/rfnoc/chdr_types.hpp @@ -313,6 +313,12 @@ public: // Functions          deserialize(buff, num_elems, conv_byte_order);      } +    // Return whether or not we have a valid timestamp +    bool has_timestamp() const +    { +        return bool(timestamp); +    } +      //! Comparison operator (==)      bool operator==(const ctrl_payload& rhs) const; diff --git a/host/lib/rfnoc/ctrlport_endpoint.cpp b/host/lib/rfnoc/ctrlport_endpoint.cpp index 3374a707b..43bbf815c 100644 --- a/host/lib/rfnoc/ctrlport_endpoint.cpp +++ b/host/lib/rfnoc/ctrlport_endpoint.cpp @@ -11,7 +11,9 @@  #include <uhdlib/rfnoc/ctrlport_endpoint.hpp>  #include <condition_variable>  #include <boost/format.hpp> +#include <deque>  #include <mutex> +#include <numeric>  #include <queue> @@ -27,6 +29,8 @@ namespace {  constexpr size_t ASYNC_MESSAGE_SIZE = 6;  //! Default completion timeout for transactions  constexpr double DEFAULT_TIMEOUT = 0.1; +//! Long timeout for when we wait on a timed command +constexpr double MASSIVE_TIMEOUT = 10.0;  //! Default value for whether ACKs are always required  constexpr bool DEFAULT_FORCE_ACKS = false;  } // namespace @@ -229,7 +233,7 @@ public:                      resp_status = RESP_SIZEERR;                  }                  // Pop the request from the queue -                _req_queue.pop(); +                _req_queue.pop_front();                  // Push the response into the response queue                  _resp_queue.push(std::make_tuple(rx_ctrl, resp_status));                  _resp_ready_cond.notify_one(); @@ -246,7 +250,7 @@ public:                  _resp_queue.push(std::make_tuple(resp, RESP_DROPPED));                  _resp_ready_cond.notify_one();                  // Pop the request from the queue -                _req_queue.pop(); +                _req_queue.pop_front();              };              // Peek at the request queue to check the expected sequence number @@ -346,6 +350,17 @@ private:          return steady_clock::now() + (static_cast<int>(std::ceil(duration / 1e-6)) * 1us);      } +    //! Returns whether or not we have a timed command queued +    bool check_timed_in_queue() const +    { +        for (auto pyld : _req_queue) { +            if (pyld.has_timestamp()) { +                return true; +            } +        } +        return false; +    } +      //! Sends a request control packet to a remote device      const ctrl_payload send_request_packet(ctrl_opcode_t op_code,          uint32_t address, @@ -394,13 +409,18 @@ private:                            - (ASYNC_MESSAGE_SIZE * _max_outstanding_async_msgs));          };          if (!buff_not_full()) { -            if (not _buff_free_cond.wait_until(lock, timeout_time, buff_not_full)) { +            // If we're sending a timed command or if we have a timed command in the +            // queue, use the MASSIVE_TIMEOUT instead +            auto timed_timeout = (check_timed_in_queue() +                                      ? start_timeout(MASSIVE_TIMEOUT) +                                      : timeout_time); +            if (not _buff_free_cond.wait_until(lock, timed_timeout, buff_not_full)) {                  throw uhd::op_timeout(                      "Control operation timed out waiting for space in command buffer");              }          }          _buff_occupied += pyld_size; -        _req_queue.push(tx_ctrl); +        _req_queue.push_back(tx_ctrl);          // Send the payload as soon as there is room in the buffer          _handle_send(tx_ctrl, _policy.timeout); @@ -497,7 +517,7 @@ private:      //! A condition variable that hold the "downstream buffer is free" condition      std::condition_variable _buff_free_cond;      //! A queue that holds all outstanding requests -    std::queue<ctrl_payload> _req_queue; +    std::deque<ctrl_payload> _req_queue;      //! A queue that holds all outstanding responses and their status      std::queue<std::tuple<ctrl_payload, response_status_t>> _resp_queue;      //! A condition variable that hold the "response is available" condition  | 
