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 ); }