aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/device3
diff options
context:
space:
mode:
authorPatrick Sisterhen <patrick.sisterhen@ni.com>2017-05-04 00:26:13 -0500
committerMartin Braun <martin.braun@ettus.com>2017-05-08 11:29:22 -0700
commitc99dde5e3fceec6f276c8f4a745458eb8937e6b3 (patch)
tree2a3bfec9f486ff62734dfa16eb6ea734ea6ce321 /host/lib/usrp/device3
parente6c8cee6e9e6dbe257bc6a77899306e611d44d71 (diff)
downloaduhd-c99dde5e3fceec6f276c8f4a745458eb8937e6b3.tar.gz
uhd-c99dde5e3fceec6f276c8f4a745458eb8937e6b3.tar.bz2
uhd-c99dde5e3fceec6f276c8f4a745458eb8937e6b3.zip
device3: Improved busy loop for tx flow control polling on slower machines
Effectively adds a yield statement inside the busy loop.
Diffstat (limited to 'host/lib/usrp/device3')
-rw-r--r--host/lib/usrp/device3/device3_io_impl.cpp30
1 files changed, 28 insertions, 2 deletions
diff --git a/host/lib/usrp/device3/device3_io_impl.cpp b/host/lib/usrp/device3/device3_io_impl.cpp
index aa84dcab0..199cb2786 100644
--- a/host/lib/usrp/device3/device3_io_impl.cpp
+++ b/host/lib/usrp/device3/device3_io_impl.cpp
@@ -356,6 +356,8 @@ static bool tx_flow_ctrl(
size_t fc_window,
managed_buffer::sptr
) {
+ bool refresh_cache = false;
+
// Busy loop waiting for flow control update. This is necessary because
// at this point there is data trying to be sent and it must be sent as
// quickly as possible when the flow control update arrives to avoid
@@ -363,6 +365,12 @@ static bool tx_flow_ctrl(
// data needs to be sent and flow control is holding it back.
while (true)
{
+ if (refresh_cache)
+ {
+ // update the cached value from the atomic
+ fc_cache->last_seq_ack_cache = fc_cache->last_seq_ack;
+ }
+
// delta is the amount of FC credit we've used up
const size_t delta = (fc_cache->last_seq_out & HW_SEQ_NUM_MASK) -
(fc_cache->last_seq_ack_cache & HW_SEQ_NUM_MASK);
@@ -373,8 +381,26 @@ static bool tx_flow_ctrl(
fc_cache->last_seq_out++; //update seq
return true;
}
- // update the cached value from the atomic
- fc_cache->last_seq_ack_cache = fc_cache->last_seq_ack;
+ else
+ {
+ if (refresh_cache)
+ {
+ // We have already refreshed the cache and still
+ // lack flow control permission to send new data.
+
+ // A true busy loop choked out the message handler
+ // thread on machines with processor limitations
+ // (too few cores). Yield to allow flow control
+ // receiver thread to operate.
+ boost::this_thread::yield();
+ }
+ else
+ {
+ // Allow the cache to refresh and try again to
+ // see if the device has granted flow control permission.
+ refresh_cache = true;
+ }
+ }
}
return false;
}