aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2019-08-30 14:46:33 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:39 -0800
commit81bd7896940dcd39181d0aee331e08abe4df1655 (patch)
tree2736571c329613eff05166448d86c8d126b2d2ea /host/lib
parent932ff0537bd61360e2ddaf211d6d2cafb0ddaa67 (diff)
downloaduhd-81bd7896940dcd39181d0aee331e08abe4df1655.tar.gz
uhd-81bd7896940dcd39181d0aee331e08abe4df1655.tar.bz2
uhd-81bd7896940dcd39181d0aee331e08abe4df1655.zip
rfnoc: ctrlport: Fixing timeouts for timed commands
When issuing a timed command, if there is no room in the command FIFO and there is a timed command queue'd up, wait for a long time before timing out.
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/include/uhdlib/rfnoc/chdr_types.hpp6
-rw-r--r--host/lib/rfnoc/ctrlport_endpoint.cpp30
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