aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/CMakeLists.txt4
-rw-r--r--host/lib/transport/libusb1_base.cpp18
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp95
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp44
-rw-r--r--host/lib/transport/usb_dummy_impl.cpp39
5 files changed, 126 insertions, 74 deletions
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index eafdd57d2..b95d46381 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -37,7 +37,9 @@ IF(LIBUSB_FOUND)
ENDIF(MSVC)
SET(HAVE_USB_SUPPORT TRUE)
ELSE(LIBUSB_FOUND)
- #TODO dummy usb
+ LIBUHD_APPEND_SOURCES(
+ ${CMAKE_SOURCE_DIR}/lib/transport/usb_dummy_impl.cpp
+ )
ENDIF(LIBUSB_FOUND)
IF(HAVE_USB_SUPPORT)
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index 910b04fc8..cfa77d9ca 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -16,12 +16,10 @@
//
#include "libusb1_base.hpp"
-#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/types/dict.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/foreach.hpp>
-#include <boost/thread.hpp>
#include <iostream>
using namespace uhd;
@@ -35,12 +33,9 @@ public:
libusb_session_impl(void){
UHD_ASSERT_THROW(libusb_init(&_context) == 0);
libusb_set_debug(_context, debug_level);
- _thread_group.create_thread(boost::bind(&libusb_session_impl::run_event_loop, this));
}
~libusb_session_impl(void){
- _running = false;
- _thread_group.join_all();
libusb_exit(_context);
}
@@ -50,19 +45,6 @@ public:
private:
libusb_context *_context;
- boost::thread_group _thread_group;
- bool _running;
-
- void run_event_loop(void){
- set_thread_priority_safe();
- _running = true;
- timeval tv;
- while(_running){
- tv.tv_sec = 0;
- tv.tv_usec = 100000; //100ms
- libusb_handle_events_timeout(this->get_context(), &tv);
- }
- }
};
libusb::session::sptr libusb::session::get_global_session(void){
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 819874483..f589d7c77 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -18,6 +18,7 @@
#include "libusb1_base.hpp"
#include <uhd/transport/usb_zero_copy.hpp>
#include <uhd/transport/bounded_buffer.hpp>
+#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/assert.hpp>
#include <boost/shared_array.hpp>
#include <boost/foreach.hpp>
@@ -26,6 +27,7 @@
#include <vector>
#include <iostream>
+using namespace uhd;
using namespace uhd::transport;
static const double CLEANUP_TIMEOUT = 0.2; //seconds
@@ -284,16 +286,24 @@ public:
libusb_zero_copy_impl(
libusb::device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
);
+ ~libusb_zero_copy_impl(void){
+ _threads_running = false;
+ _thread_group.join_all();
+ }
+
managed_recv_buffer::sptr get_recv_buff(double);
managed_send_buffer::sptr get_send_buff(double);
- size_t get_num_recv_frames(void) const { return _recv_num_frames; }
- size_t get_num_send_frames(void) const { return _send_num_frames; }
+ size_t get_num_recv_frames(void) const { return _num_recv_frames; }
+ size_t get_num_send_frames(void) const { return _num_send_frames; }
+
+ size_t get_recv_frame_size(void) const { return _recv_frame_size; }
+ size_t get_send_frame_size(void) const { return _send_frame_size; }
private:
void release(libusb_transfer *lut){
@@ -311,9 +321,25 @@ private:
}
libusb::device_handle::sptr _handle;
- size_t _recv_xfer_size, _send_xfer_size;
- size_t _recv_num_frames, _send_num_frames;
+ const size_t _recv_frame_size, _num_recv_frames;
+ const size_t _send_frame_size, _num_send_frames;
usb_endpoint::sptr _recv_ep, _send_ep;
+
+ //event handler threads
+ boost::thread_group _thread_group;
+ bool _threads_running;
+
+ void run_event_loop(void){
+ set_thread_priority_safe();
+ libusb::session::sptr session = libusb::session::get_global_session();
+ _threads_running = true;
+ while(_threads_running){
+ timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000; //100ms
+ libusb_handle_events_timeout(session->get_context(), &tv);
+ }
+ }
};
/*
@@ -323,24 +349,16 @@ private:
*/
libusb_zero_copy_impl::libusb_zero_copy_impl(
libusb::device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
-){
- _handle = handle;
-
- //if the sizes are left at 0 (automatic) -> use the defaults
- if (recv_xfer_size == 0) recv_xfer_size = DEFAULT_XFER_SIZE;
- if (recv_num_xfers == 0) recv_num_xfers = DEFAULT_NUM_XFERS;
- if (send_xfer_size == 0) send_xfer_size = DEFAULT_XFER_SIZE;
- if (send_num_xfers == 0) send_num_xfers = DEFAULT_NUM_XFERS;
-
- //store the num xfers for the num frames count
- _recv_xfer_size = recv_xfer_size;
- _recv_num_frames = recv_num_xfers;
- _send_xfer_size = send_xfer_size;
- _send_num_frames = send_num_xfers;
-
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
+):
+ _handle(handle),
+ _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", DEFAULT_XFER_SIZE))),
+ _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_XFERS))),
+ _send_frame_size(size_t(hints.cast<double>("send_frame_size", DEFAULT_XFER_SIZE))),
+ _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_XFERS)))
+{
_handle->claim_interface(2 /*in interface*/);
_handle->claim_interface(1 /*out interface*/);
@@ -348,17 +366,23 @@ libusb_zero_copy_impl::libusb_zero_copy_impl(
_handle, // libusb device_handle
recv_endpoint, // USB endpoint number
true, // IN endpoint
- recv_xfer_size, // buffer size per transfer
- recv_num_xfers // number of libusb transfers
+ this->get_recv_frame_size(), // buffer size per transfer
+ this->get_num_recv_frames() // number of libusb transfers
));
_send_ep = usb_endpoint::sptr(new usb_endpoint(
_handle, // libusb device_handle
send_endpoint, // USB endpoint number
false, // OUT endpoint
- send_xfer_size, // buffer size per transfer
- send_num_xfers // number of libusb transfers
+ this->get_send_frame_size(), // buffer size per transfer
+ this->get_num_send_frames() // number of libusb transfers
));
+
+ //spawn the event handler threads
+ size_t concurrency = hints.cast<size_t>("concurrency_hint", 1);
+ for (size_t i = 0; i < concurrency; i++) _thread_group.create_thread(
+ boost::bind(&libusb_zero_copy_impl::run_event_loop, this)
+ );
}
/*
@@ -394,7 +418,7 @@ managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(double timeout){
}
else {
return managed_send_buffer::make_safe(
- boost::asio::mutable_buffer(lut->buffer, _send_xfer_size),
+ boost::asio::mutable_buffer(lut->buffer, this->get_send_frame_size()),
boost::bind(&libusb_zero_copy_impl::commit, shared_from_this(), lut, _1)
);
}
@@ -405,17 +429,14 @@ managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(double timeout){
**********************************************************************/
usb_zero_copy::sptr usb_zero_copy::make(
usb_device_handle::sptr handle,
- unsigned int recv_endpoint, unsigned int send_endpoint,
- size_t recv_xfer_size, size_t recv_num_xfers,
- size_t send_xfer_size, size_t send_num_xfers
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints
){
libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(
boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()
));
return sptr(new libusb_zero_copy_impl(
- dev_handle,
- recv_endpoint, send_endpoint,
- recv_xfer_size, recv_num_xfers,
- send_xfer_size, send_num_xfers
+ dev_handle, recv_endpoint, send_endpoint, hints
));
}
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index e9d91fe45..7e28caf2d 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -44,7 +44,7 @@ static const size_t MIN_RECV_SOCK_BUFF_SIZE = size_t(4 * 25e6 * 0.5);
static const size_t MIN_SEND_SOCK_BUFF_SIZE = size_t(10e3);
//the number of async frames to allocate for each send and recv
-static const size_t DEFAULT_NUM_ASYNC_FRAMES = 32;
+static const size_t DEFAULT_NUM_FRAMES = 32;
//a single concurrent thread for io_service seems to be the fastest
static const size_t CONCURRENCY_HINT = 1;
@@ -61,14 +61,15 @@ public:
typedef boost::shared_ptr<udp_zero_copy_asio_impl> sptr;
udp_zero_copy_asio_impl(
- const std::string &addr, const std::string &port,
- size_t recv_frame_size, size_t num_recv_frames,
- size_t send_frame_size, size_t num_send_frames
+ const std::string &addr,
+ const std::string &port,
+ const device_addr_t &hints
):
- _io_service(CONCURRENCY_HINT),
- _work(new asio::io_service::work(_io_service)),
- _recv_frame_size(recv_frame_size), _num_recv_frames(num_recv_frames),
- _send_frame_size(send_frame_size), _num_send_frames(num_send_frames)
+ _io_service(hints.cast<size_t>("concurrency_hint", CONCURRENCY_HINT)),
+ _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", udp_simple::mtu))),
+ _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_FRAMES))),
+ _send_frame_size(size_t(hints.cast<double>("send_frame_size", udp_simple::mtu))),
+ _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_FRAMES)))
{
//std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl;
@@ -99,6 +100,7 @@ public:
}
//spawn the service threads that will run the io service
+ _work = new asio::io_service::work(_io_service); //new work to delete later
for (size_t i = 0; i < CONCURRENCY_HINT; i++) _thread_group.create_thread(
boost::bind(&udp_zero_copy_asio_impl::service, this)
);
@@ -141,6 +143,7 @@ public:
}
size_t get_num_recv_frames(void) const {return _num_recv_frames;}
+ size_t get_recv_frame_size(void) const {return _recv_frame_size;}
//! pop an empty send buffer off of the fifo and bind with the commit callback
managed_send_buffer::sptr get_send_buff(double timeout){
@@ -159,6 +162,7 @@ public:
}
size_t get_num_send_frames(void) const {return _num_send_frames;}
+ size_t get_send_frame_size(void) const {return _send_frame_size;}
private:
void service(void){
@@ -242,9 +246,12 @@ template<typename Opt> static void resize_buff_helper(
"Current %s sock buff size: %d bytes"
) % name % actual_size << std::endl;
if (actual_size < target_size) uhd::print_warning(str(boost::format(
- "The %s buffer is smaller than the requested size.\n"
- "The minimum recommended buffer size is %d bytes.\n"
- "See the USRP2 application notes on buffer resizing.\n"
+ "The %1% buffer is smaller than the requested size.\n"
+ "The minimum recommended buffer size is %2% bytes.\n"
+ "See the transport application notes on buffer resizing.\n"
+ #if defined(UHD_PLATFORM_LINUX)
+ "Please run: sudo sysctl -w net.core.rmem_max=%2%\n"
+ #endif /*defined(UHD_PLATFORM_LINUX)*/
) % name % min_sock_buff_size));
}
@@ -260,14 +267,15 @@ template<typename Opt> static void resize_buff_helper(
udp_zero_copy::sptr udp_zero_copy::make(
const std::string &addr,
const std::string &port,
- size_t recv_buff_size,
- size_t send_buff_size
+ const device_addr_t &hints
){
- udp_zero_copy_asio_impl::sptr udp_trans(new udp_zero_copy_asio_impl(
- addr, port,
- udp_simple::mtu, DEFAULT_NUM_ASYNC_FRAMES, //recv
- udp_simple::mtu, DEFAULT_NUM_ASYNC_FRAMES //send
- ));
+ udp_zero_copy_asio_impl::sptr udp_trans(
+ new udp_zero_copy_asio_impl(addr, port, hints)
+ );
+
+ //extract buffer size hints from the device addr
+ size_t recv_buff_size = size_t(hints.cast<double>("recv_buff_size", 0.0));
+ size_t send_buff_size = size_t(hints.cast<double>("send_buff_size", 0.0));
//call the helper to resize send and recv buffers
resize_buff_helper<asio::socket_base::receive_buffer_size>(udp_trans, recv_buff_size, "recv");
diff --git a/host/lib/transport/usb_dummy_impl.cpp b/host/lib/transport/usb_dummy_impl.cpp
new file mode 100644
index 000000000..8a9772e7f
--- /dev/null
+++ b/host/lib/transport/usb_dummy_impl.cpp
@@ -0,0 +1,39 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/transport/usb_device_handle.hpp>
+#include <uhd/transport/usb_control.hpp>
+#include <uhd/transport/usb_zero_copy.hpp>
+#include <uhd/utils/exception.hpp>
+
+using namespace uhd;
+using namespace uhd::transport;
+
+std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(boost::uint16_t, boost::uint16_t){
+ return std::vector<usb_device_handle::sptr>(); //empty list
+}
+
+usb_control::sptr usb_control::make(usb_device_handle::sptr){
+ throw std::runtime_error("no usb support -> usb_control::make not implemented");
+}
+
+usb_zero_copy::sptr usb_zero_copy::make(
+ usb_device_handle::sptr,
+ size_t, size_t, const device_addr_t &
+){
+ throw std::runtime_error("no usb support -> usb_zero_copy::make not implemented");
+}