Exemple #1
0
 UHD_INLINE bool spin_wait_with_timeout(
     std::atomic<T> &cond,
     const T value,
     const double timeout
 ){
     if (cond == value) return true;
     const time_spec_t exit_time = time_spec_t::get_system_time() + time_spec_t(timeout);
     while (cond != value) {
         if (time_spec_t::get_system_time() > exit_time) {
             return false;
         }
         boost::this_thread::interruption_point();
         boost::this_thread::yield();
     }
     return true;
 }
    /*******************************************************************
     * Send:
     * The entry point for the fast-path send calls.
     * Dispatch into combinations of single packet send calls.
     ******************************************************************/
    UHD_INLINE size_t send(
        const uhd::tx_streamer::buffs_type &buffs,
        const size_t nsamps_per_buff,
        const uhd::tx_metadata_t &metadata,
        const double timeout
    ){
        //translate the metadata to vrt if packet info
        vrt::if_packet_info_t if_packet_info;
        if_packet_info.has_sid = false;
        if_packet_info.has_cid = false;
        if_packet_info.has_tlr = false;
        if_packet_info.has_tsi = metadata.has_time_spec;
        if_packet_info.has_tsf = metadata.has_time_spec;
        if_packet_info.tsi     = boost::uint32_t(metadata.time_spec.get_full_secs());
        if_packet_info.tsf     = boost::uint64_t(metadata.time_spec.get_tick_count(_tick_rate));
        if_packet_info.sob     = metadata.start_of_burst;
        if_packet_info.eob     = metadata.end_of_burst;

        if (nsamps_per_buff <= _max_samples_per_packet){

            //TODO remove this code when sample counts of zero are supported by hardware
            #ifndef SSPH_DONT_PAD_TO_ONE
            if (nsamps_per_buff == 0) return send_one_packet(
                _zero_buffs, 1, if_packet_info, timeout
            ) & 0x0;
            #endif

            return send_one_packet(buffs, nsamps_per_buff, if_packet_info, timeout);
        }
        size_t total_num_samps_sent = 0;

        //false until final fragment
        if_packet_info.eob = false;

        const size_t num_fragments = (nsamps_per_buff-1)/_max_samples_per_packet;
        const size_t final_length = ((nsamps_per_buff-1)%_max_samples_per_packet)+1;

        //loop through the following fragment indexes
        for (size_t i = 0; i < num_fragments; i++){

            //send a fragment with the helper function
            const size_t num_samps_sent = send_one_packet(
                buffs, _max_samples_per_packet,
                if_packet_info, timeout,
                total_num_samps_sent*_bytes_per_cpu_item
            );
            total_num_samps_sent += num_samps_sent;
            if (num_samps_sent == 0) return total_num_samps_sent;

            //setup metadata for the next fragment
            const time_spec_t time_spec = metadata.time_spec + time_spec_t(0, total_num_samps_sent, _samp_rate);
            if_packet_info.tsi = boost::uint32_t(time_spec.get_full_secs());
            if_packet_info.tsf = boost::uint64_t(time_spec.get_tick_count(_tick_rate));
            if_packet_info.sob = false;

        }

        //send the final fragment with the helper function
        if_packet_info.eob = metadata.end_of_burst;
        return total_num_samps_sent + send_one_packet(
            buffs, final_length,
            if_packet_info, timeout,
            total_num_samps_sent*_bytes_per_cpu_item
        );
    }