From f662aeaff39e211b4ca1e92f55844b5e36592845 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 20 Jul 2020 19:11:56 +0200 Subject: [PATCH] Remove unnecessary zero memory (#1564) * RF drivers to allow nullptr buffers in send/recv * Remove zeromem from radio * remove unused buffers --- lib/include/srslte/radio/radio.h | 1 - lib/src/phy/rf/rf_blade_imp.c | 22 ++++++++++-- lib/src/phy/rf/rf_soapy_imp.c | 26 ++++++++++---- lib/src/phy/rf/rf_uhd_imp.cc | 29 +++++++++++----- lib/src/phy/rf/rf_zmq_imp.c | 4 +-- lib/src/radio/radio.cc | 59 +++++++++++++++----------------- 6 files changed, 89 insertions(+), 52 deletions(-) diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 044e03f8f..33cdbc2c7 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -102,7 +102,6 @@ private: log_filter* log_h = nullptr; srslte::logger* logger = nullptr; phy_interface_radio* phy = nullptr; - cf_t* zeros = nullptr; rf_timestamp_t end_of_burst_time = {}; bool is_start_of_burst = false; diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index c365b108b..8d70e5429 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -29,6 +29,8 @@ #define UNUSED __attribute__((unused)) #define CONVERT_BUFFER_SIZE (240 * 1024) +cf_t zero_mem[64 * 1024]; + typedef struct { struct bladerf* dev; bladerf_sample_rate rx_rate; @@ -418,7 +420,11 @@ int rf_blade_recv_with_time_multi(void* h, time_t* secs, double* frac_secs) { - return rf_blade_recv_with_time(h, *data, nsamples, blocking, secs, frac_secs); + void* ptr = NULL; + if (data != NULL) { + ptr = data[0]; + } + return rf_blade_recv_with_time(h, ptr, nsamples, blocking, secs, frac_secs); } int rf_blade_recv_with_time(void* h, @@ -456,7 +462,9 @@ int rf_blade_recv_with_time(void* h, } timestamp_to_secs(handler->rx_rate, meta.timestamp, secs, frac_secs); - srslte_vec_convert_if(handler->rx_buffer, 2048, data, 2 * nsamples); + if (data != NULL) { + srslte_vec_convert_if(handler->rx_buffer, 2048, data, 2 * nsamples); + } return nsamples; } @@ -471,8 +479,12 @@ int rf_blade_send_timed_multi(void* h, bool is_start_of_burst, bool is_end_of_burst) { + void* ptr = NULL; + if (data != NULL) { + ptr = data[0]; + } return rf_blade_send_timed( - h, data[0], nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); + h, ptr, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); } int rf_blade_send_timed(void* h, @@ -498,6 +510,10 @@ int rf_blade_send_timed(void* h, return -1; } + if (data == NULL) { + data = zero_mem; + } + srslte_vec_convert_fi(data, 2048, handler->tx_buffer, 2 * nsamples); memset(&meta, 0, sizeof(meta)); diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 0a8e52264..05698da26 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -74,6 +74,7 @@ typedef struct { } rf_soapy_handler_t; cf_t zero_mem[64 * 1024]; +cf_t dummy_mem[64 * 1024]; static void log_overflow(rf_soapy_handler_t* h) { @@ -823,9 +824,16 @@ int rf_soapy_recv_with_time_multi(void* h, #endif void* buffs_ptr[SRSLTE_MAX_PORTS] = {}; - for (int i = 0; i < handler->num_rx_channels; i++) { - cf_t* data_c = (cf_t*)data[i]; - buffs_ptr[i] = &data_c[n]; + + if (data != NULL) { + for (int i = 0; i < handler->num_rx_channels; i++) { + cf_t* data_c = (cf_t*)data[i] ? data[i] : dummy_mem; + buffs_ptr[i] = &data_c[n]; + } + } else { + for (int i = 0; i < handler->num_rx_channels; i++) { + buffs_ptr[i] = dummy_mem; + } } ret = SoapySDRDevice_readStream( @@ -943,9 +951,15 @@ int rf_soapy_send_timed_multi(void* h, #endif const void* buffs_ptr[SRSLTE_MAX_PORTS] = {}; - for (int i = 0; i < handler->num_tx_channels; i++) { - cf_t* data_c = data[i] ? data[i] : zero_mem; - buffs_ptr[i] = &data_c[n]; + if (data != NULL) { + for (int i = 0; i < handler->num_tx_channels; i++) { + cf_t* data_c = data[i] ? data[i] : zero_mem; + buffs_ptr[i] = &data_c[n]; + } + } else { + for (int i = 0; i < handler->num_rx_channels; i++) { + buffs_ptr[i] = zero_mem; + } } ret = SoapySDRDevice_writeStream( diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index c0c28fd2f..d28d96657 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -154,7 +154,8 @@ void suppress_handler(const char* x) // do nothing } -static cf_t zero_mem[64 * 1024] = {}; +static cf_t zero_mem[64 * 1024] = {}; +static cf_t dummy_mem[64 * 1024] = {}; #define print_usrp_error(h) \ do { \ @@ -1171,9 +1172,15 @@ int rf_uhd_recv_with_time_multi(void* h, // Receive stream in multiple blocks while (rxd_samples_total < nsamples && trials < RF_UHD_IMP_MAX_RX_TRIALS) { void* buffs_ptr[SRSLTE_MAX_CHANNELS] = {}; - for (uint32_t i = 0; i < handler->nof_rx_channels; i++) { - cf_t* data_c = (cf_t*)data[i]; - buffs_ptr[i] = &data_c[rxd_samples_total]; + if (data != nullptr) { + for (uint32_t i = 0; i < handler->nof_rx_channels; i++) { + cf_t* data_c = (cf_t*)(data[i] ? data[i] : dummy_mem); + buffs_ptr[i] = &data_c[rxd_samples_total]; + } + } else { + for (uint32_t i = 0; i < handler->nof_rx_channels; i++) { + buffs_ptr[i] = dummy_mem; + } } size_t num_samps_left = nsamples - rxd_samples_total; @@ -1310,10 +1317,16 @@ int rf_uhd_send_timed_multi(void* h, // Generate transmission buffer pointers cf_t* data_c[SRSLTE_MAX_CHANNELS] = {}; - for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { - if (i < handler->nof_tx_channels) { - data_c[i] = (data[i] != nullptr) ? (cf_t*)(data[i]) : zero_mem; - } else { + if (data != nullptr) { + for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { + if (i < handler->nof_tx_channels) { + data_c[i] = (data[i] != nullptr) ? (cf_t*)(data[i]) : zero_mem; + } else { + data_c[i] = zero_mem; + } + } + } else { + for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { data_c[i] = zero_mem; } } diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index ee3fe3442..1571dc6cb 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -613,7 +613,7 @@ int rf_zmq_recv_with_time_multi(void* h, // Traverse all channels, break if mapped if (buffers[j] == NULL && rf_zmq_rx_match_freq(&handler->receiver[j], handler->rx_freq_mhz[i])) { // Available buffer and matched frequency with receiver - buffers[j] = (cf_t*)data[i]; + buffers[j] = (cf_t*)(data != NULL ? data[i] : NULL); mapped = true; } } @@ -822,7 +822,7 @@ int rf_zmq_send_timed_multi(void* h, // Traverse all channels, break if mapped if (buffers[j] == NULL && rf_zmq_tx_match_freq(&handler->transmitter[j], handler->tx_freq_mhz[i])) { // Available buffer and matched frequency with receiver - buffers[j] = (cf_t*)data[i]; + buffers[j] = (cf_t*)(data != NULL ? data[i] : NULL); mapped = true; } } diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 400151019..b20ec56d1 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -28,24 +28,16 @@ namespace srslte { -radio::radio(srslte::log_filter* log_h_) : logger(nullptr), log_h(log_h_), zeros(nullptr) +radio::radio(srslte::log_filter* log_h_) : logger(nullptr), log_h(log_h_) { - zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); - srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX); } -radio::radio(srslte::logger* logger_) : logger(logger_), log_h(nullptr), zeros(nullptr) +radio::radio(srslte::logger* logger_) : logger(logger_), log_h(nullptr) { - zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX); - srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX); } radio::~radio() { - if (zeros) { - free(zeros); - zeros = nullptr; - } } int radio::init(const rf_args_t& args, phy_interface_radio* phy_) @@ -181,10 +173,6 @@ bool radio::is_init() void radio::stop() { - if (zeros) { - free(zeros); - zeros = NULL; - } if (is_initialized) { for (srslte_rf_t& rf_device : rf_devices) { srslte_rf_close(&rf_device); @@ -234,11 +222,12 @@ bool radio::start_agc(bool tx_gain_same_rx) return true; } -bool radio::rx_now(rf_buffer_interface& buffer, rf_timestamp_interface& rxd_time) +bool radio::rx_now(rf_buffer_interface& rx_buffer, rf_timestamp_interface& rxd_time) { bool ret = true; if (not radio_is_streaming) { + log_h->info("Starting streaming\n"); for (srslte_rf_t& rf_device : rf_devices) { srslte_rf_start_rx_stream(&rf_device, false); } @@ -246,13 +235,13 @@ bool radio::rx_now(rf_buffer_interface& buffer, rf_timestamp_interface& rxd_time } for (uint32_t device_idx = 0; device_idx < (uint32_t)rf_devices.size(); device_idx++) { - ret &= rx_dev(device_idx, buffer, rxd_time.get_ptr(device_idx)); + ret &= rx_dev(device_idx, rx_buffer, rxd_time.get_ptr(device_idx)); } return ret; } -bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer, srslte_timestamp_t* rxd_time) +bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& rx_buffer, srslte_timestamp_t* rxd_time) { if (!is_initialized) { return false; @@ -262,14 +251,14 @@ bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer double* frac_secs = rxd_time ? &rxd_time->frac_secs : nullptr; void* radio_buffers[SRSLTE_MAX_CHANNELS] = {}; - if (not map_channels(rx_channel_mapping, device_idx, 0, buffer, radio_buffers)) { + if (not map_channels(rx_channel_mapping, device_idx, 0, rx_buffer, radio_buffers)) { log_h->error("Mapping logical channels to physical channels for transmission\n"); return false; } // Apply Rx offset into the number of samples and reset value int nof_samples_offset = rx_offset_n.at(device_idx); - uint32_t nof_samples = buffer.get_nof_samples(); + uint32_t nof_samples = rx_buffer.get_nof_samples(); // Number of samples adjust from device time offset if (nof_samples_offset < 0 and (uint32_t)(-nof_samples_offset) > nof_samples) { @@ -281,18 +270,18 @@ bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer } // Subtract number of offset samples - rx_offset_n.at(device_idx) = nof_samples_offset - ((int)nof_samples - (int)buffer.get_nof_samples()); + rx_offset_n.at(device_idx) = nof_samples_offset - ((int)nof_samples - (int)rx_buffer.get_nof_samples()); int ret = srslte_rf_recv_with_time_multi(&rf_devices[device_idx], radio_buffers, nof_samples, true, full_secs, frac_secs); // If the number of received samples filled the buffer, there is nothing else to do - if (buffer.get_nof_samples() <= nof_samples) { + if (rx_buffer.get_nof_samples() <= nof_samples) { return ret > 0; } // Otherwise, set rest of buffer to zero - uint32_t nof_zeros = buffer.get_nof_samples() - nof_samples; + uint32_t nof_zeros = rx_buffer.get_nof_samples() - nof_samples; for (auto& b : radio_buffers) { if (b != nullptr) { cf_t* ptr = (cf_t*)b; @@ -303,12 +292,12 @@ bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer return ret > 0; } -bool radio::tx(rf_buffer_interface& buffer, const rf_timestamp_interface& tx_time) +bool radio::tx(rf_buffer_interface& rx_buffer, const rf_timestamp_interface& tx_time) { bool ret = true; for (uint32_t device_idx = 0; device_idx < (uint32_t)rf_devices.size(); device_idx++) { - ret &= tx_dev(device_idx, buffer, tx_time.get(device_idx)); + ret &= tx_dev(device_idx, rx_buffer, tx_time.get(device_idx)); } is_start_of_burst = false; @@ -352,9 +341,9 @@ bool radio::open_dev(const uint32_t& device_idx, const std::string& device_name, return true; } -bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, const srslte_timestamp_t& tx_time_) +bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& rx_buffer, const srslte_timestamp_t& tx_time_) { - uint32_t nof_samples = buffer.get_nof_samples(); + uint32_t nof_samples = rx_buffer.get_nof_samples(); uint32_t sample_offset = 0; srslte_rf_t* rf_device = &rf_devices[device_idx]; @@ -407,7 +396,7 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons // Zeros transmission int ret = srslte_rf_send_timed2(rf_device, - zeros, + nullptr, nzeros, end_of_burst_time[device_idx].full_secs, end_of_burst_time[device_idx].frac_secs, @@ -432,7 +421,13 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons srslte_timestamp_add(&end_of_burst_time[device_idx], 0, (double)nof_samples / cur_tx_srate); void* radio_buffers[SRSLTE_MAX_CHANNELS] = {}; - if (not map_channels(tx_channel_mapping, device_idx, sample_offset, buffer, radio_buffers)) { + + // Discard channels not allocated, need to point to valid buffer + for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { + radio_buffers[i] = nullptr; + } + + if (not map_channels(tx_channel_mapping, device_idx, sample_offset, rx_buffer, radio_buffers)) { log_h->error("Mapping logical channels to physical channels for transmission\n"); return false; } @@ -451,7 +446,7 @@ void radio::tx_end() if (!is_start_of_burst) { for (uint32_t i = 0; i < (uint32_t)rf_devices.size(); i++) { srslte_rf_send_timed2( - &rf_devices[i], zeros, 0, end_of_burst_time[i].full_secs, end_of_burst_time[i].frac_secs, false, true); + &rf_devices[i], nullptr, 0, end_of_burst_time[i].full_secs, end_of_burst_time[i].frac_secs, false, true); } is_start_of_burst = true; } @@ -833,12 +828,12 @@ void radio::rf_msg_callback(void* arg, srslte_rf_error_t error) bool radio::map_channels(channel_mapping& map, uint32_t device_idx, uint32_t sample_offset, - const rf_buffer_interface& buffer, + const rf_buffer_interface& rx_buffer, void* radio_buffers[SRSLTE_MAX_CHANNELS]) { // Discard channels not allocated, need to point to valid buffer for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) { - radio_buffers[i] = zeros; + radio_buffers[i] = nullptr; } // Conversion from safe C++ std::array to the unsafe C interface. We must ensure that the RF driver implementation // accepts up to SRSLTE_MAX_CHANNELS buffers @@ -867,7 +862,7 @@ bool radio::map_channels(channel_mapping& map, // Set pointer if device index matches if (rf_device_idx == device_idx) { - cf_t* ptr = buffer.get(i, j, nof_antennas); + cf_t* ptr = rx_buffer.get(i, j, nof_antennas); // Add sample offset only if it is a valid pointer if (ptr != nullptr) {