diff options
| -rw-r--r-- | host/include/uhd/transport/udp_zero_copy.hpp | 2 | ||||
| -rw-r--r-- | host/lib/transport/udp_wsa_zero_copy.cpp | 79 | 
2 files changed, 79 insertions, 2 deletions
| diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 8fb5115c2..de4721be0 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -56,6 +56,8 @@ public:       *       * \param addr a string representing the destination address       * \param port a string representing the destination port +     * \param default_buff_args Default values for frame sizes and num frames +     * \param[out] buff_params_out Returns the actual buffer sizes       * \param hints optional parameters to pass to the underlying transport       */      static sptr make( diff --git a/host/lib/transport/udp_wsa_zero_copy.cpp b/host/lib/transport/udp_wsa_zero_copy.cpp index 031d26374..23ccf7975 100644 --- a/host/lib/transport/udp_wsa_zero_copy.cpp +++ b/host/lib/transport/udp_wsa_zero_copy.cpp @@ -276,6 +276,34 @@ 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;} +    //! Read back the socket's buffer space reserved for receives +    size_t get_recv_buff_size(void) { +        int recv_buff_size = 0; +        getsockopt( +                _sock_fd, +                SOL_SOCKET, +                SO_RCVBUF, +                (const char *)&recv_buff_size, +                sizeof(recv_buff_size) +        ); + +        return (size_t) recv_buff_size; +    } + +    //! Read back the socket's buffer space reserved for sends +    size_t get_send_buff_size(void) { +        int send_buff_size = 0; +        getsockopt( +                _sock_fd, +                SOL_SOCKET, +                SO_SNDBUF, +                (const char *)&send_buff_size, +                sizeof(send_buff_size) +        ); + +        return (size_t) send_buff_size; +    } +  private:      //memory management -> buffers and fifos      const size_t _recv_frame_size, _num_recv_frames; @@ -292,6 +320,25 @@ private:  /***********************************************************************   * UDP zero copy make function   **********************************************************************/ +void check_usr_buff_size( +    size_t actual_buff_size, +    size_t user_buff_size, // Set this to zero for no user-defined preference +    const std::string tx_rx +){ +    UHD_LOG << boost::format( +        "Target %s sock buff size: %d bytes\n" +        "Actual %s sock buff size: %d bytes" +    ) % tx_rx % user_buff_size % tx_rx % actual_buff_size << std::endl; +    if ((user_buff_size != 0.0) and (actual_buff_size < user_buff_size)) UHD_MSG(warning) << boost::format( +        "The %s buffer could not be resized sufficiently.\n" +        "Target sock buff size: %d bytes.\n" +        "Actual sock buff size: %d bytes.\n" +        "See the transport application notes on buffer resizing.\n%s" +    ) % tx_rx % user_buff_size % actual_buff_size; +} + + +  udp_zero_copy::sptr udp_zero_copy::make(      const std::string &addr,      const std::string &port, @@ -306,6 +353,34 @@ udp_zero_copy::sptr udp_zero_copy::make(      xport_params.num_recv_frames = size_t(hints.cast<double>("num_recv_frames", default_buff_args.num_recv_frames));      xport_params.send_frame_size = size_t(hints.cast<double>("send_frame_size", default_buff_args.send_frame_size));      xport_params.num_send_frames = size_t(hints.cast<double>("num_send_frames", default_buff_args.num_send_frames)); -     -    return sptr(new udp_zero_copy_wsa_impl(addr, port, xport_params, hints)); + +    //extract buffer size hints from the device addr and check if they match up +    size_t usr_recv_buff_size = size_t(hints.cast<double>("recv_buff_size", 0.0)); +    size_t usr_send_buff_size = size_t(hints.cast<double>("send_buff_size", 0.0)); +    if (hints.has_key("recv_buff_size")) { +        if (usr_recv_buff_size < xport_params.recv_frame_size * xport_params.num_recv_frames) { +            throw uhd::value_error((boost::format( +                "recv_buff_size must be equal to or greater than (num_recv_frames * recv_frame_size) where num_recv_frames=%d, recv_frame_size=%d") +                % xport_params.num_recv_frames % xport_params.recv_frame_size).str()); +        } +    } +    if (hints.has_key("send_buff_size")) { +        if (usr_send_buff_size < xport_params.send_frame_size * xport_params.num_send_frames) { +            throw uhd::value_error((boost::format( +                "send_buff_size must be equal to or greater than (num_send_frames * send_frame_size) where num_send_frames=%d, send_frame_size=%d") +                % xport_params.num_send_frames % xport_params.send_frame_size).str()); +        } +    } + +    udp_zero_copy_wsa_impl::sptr udp_trans( +        new udp_zero_copy_wsa_impl(addr, port, xport_params, hints) +    ); + +    // Read back the actual socket buffer sizes +    buff_params_out.recv_buff_size = udp_trans->get_recv_buff_size(); +    buff_params_out.send_buff_size = udp_trans->get_send_buff_size(); +    check_usr_buff_size(buff_params_out.recv_buff_size, usr_recv_buff_size, "recv"); +    check_usr_buff_size(buff_params_out.send_buff_size, usr_send_buff_size, "send"); + +    return udp_trans;  } | 
