Fix UHD memory issues

This commit is contained in:
Xavier Arteaga 2020-03-18 15:24:53 +01:00 committed by Xavier Arteaga
parent f3f03ad12d
commit ea1b6b60dd
3 changed files with 91 additions and 40 deletions

View File

@ -151,6 +151,77 @@ static void* async_thread(void* h)
} }
#endif #endif
static inline void uhd_free(rf_uhd_handler_t* h)
{
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
// NULL handler, return
if (!handler) {
return;
}
uhd_tx_metadata_free(&handler->tx_md);
uhd_rx_metadata_free(&handler->rx_md_first);
uhd_rx_metadata_free(&handler->rx_md);
#if HAVE_ASYNC_THREAD
if (handler->async_thread_running) {
handler->async_thread_running = false;
pthread_join(handler->async_thread, NULL);
}
#endif
uhd_tx_streamer_free(&handler->tx_stream);
uhd_rx_streamer_free(&handler->rx_stream);
uhd_usrp_free(&handler->usrp);
free(handler);
}
static inline int uhd_alloc(rf_uhd_handler_t* handler, char* args)
{
uhd_error error;
error = uhd_usrp_make(&handler->usrp, args);
if (error) {
ERROR("Error opening UHD: code %d\n", error);
return SRSLTE_ERROR;
}
error = uhd_rx_streamer_make(&handler->rx_stream);
if (error) {
ERROR("Error making RX stream: %d\n", error);
return SRSLTE_ERROR;
}
error = uhd_tx_streamer_make(&handler->tx_stream);
if (error) {
ERROR("Error making TX stream: %d\n", error);
return SRSLTE_ERROR;
}
// Make metadata objects for RX/TX
error = uhd_rx_metadata_make(&handler->rx_md);
if (error) {
ERROR("Error making RX Metadata: %d\n", error);
return SRSLTE_ERROR;
}
error = uhd_rx_metadata_make(&handler->rx_md_first);
if (error) {
ERROR("Error making RX Metadata first: %d\n", error);
return SRSLTE_ERROR;
}
error = uhd_tx_metadata_make(&handler->tx_md, false, 0, 0, false, false);
if (error) {
ERROR("Error making TX Metadata: %d\n", error);
return SRSLTE_ERROR;
}
return SRSLTE_SUCCESS;
}
void rf_uhd_suppress_stdout(void* h) void rf_uhd_suppress_stdout(void* h)
{ {
rf_uhd_register_msg_handler_c(suppress_handler); rf_uhd_register_msg_handler_c(suppress_handler);
@ -404,6 +475,8 @@ int rf_uhd_open(char* args, void** h)
int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels) int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
{ {
uhd_error error;
if (h) { if (h) {
*h = NULL; *h = NULL;
@ -568,10 +641,8 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
/* Create UHD handler */ /* Create UHD handler */
printf("Opening USRP channels=%d, args: %s\n", nof_channels, args); printf("Opening USRP channels=%d, args: %s\n", nof_channels, args);
uhd_error error = uhd_usrp_make(&handler->usrp, args); if (uhd_alloc(handler, args)) {
if (error) { uhd_free(handler);
fprintf(stderr, "Error opening UHD: code %d\n", error);
free(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -669,15 +740,16 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
} }
/* Initialize rx and tx stremers */ /* Initialize rx and tx stremers */
uhd_rx_streamer_make(&handler->rx_stream);
error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args, handler->rx_stream); error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args, handler->rx_stream);
if (error) { if (error) {
uhd_free(handler);
ERROR("Error opening RX stream: %d\n", error); ERROR("Error opening RX stream: %d\n", error);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
uhd_tx_streamer_make(&handler->tx_stream);
error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args, handler->tx_stream); error = uhd_usrp_get_tx_stream(handler->usrp, &stream_args, handler->tx_stream);
if (error) { if (error) {
uhd_free(handler);
ERROR("Error opening TX stream: %d\n", error); ERROR("Error opening TX stream: %d\n", error);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -699,11 +771,6 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
uhd_meta_range_stop(tx_gain_range, &handler->info.max_tx_gain); uhd_meta_range_stop(tx_gain_range, &handler->info.max_tx_gain);
uhd_meta_range_free(&tx_gain_range); uhd_meta_range_free(&tx_gain_range);
// Make metadata objects for RX/TX
uhd_rx_metadata_make(&handler->rx_md);
uhd_rx_metadata_make(&handler->rx_md_first);
uhd_tx_metadata_make(&handler->tx_md, false, 0, 0, false, false);
// Set starting gain to half maximum in case of using AGC // Set starting gain to half maximum in case of using AGC
rf_uhd_set_rx_gain(handler, handler->info.max_rx_gain * 0.7); rf_uhd_set_rx_gain(handler, handler->info.max_rx_gain * 0.7);
@ -712,7 +779,8 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
// Start low priority thread to receive async commands // Start low priority thread to receive async commands
handler->async_thread_running = true; handler->async_thread_running = true;
if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) { if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) {
perror("pthread_create"); uhd_free(handler);
ERROR("pthread_create\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
} }
@ -721,7 +789,7 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
/* Restore priorities */ /* Restore priorities */
uhd_set_thread_priority(0, false); uhd_set_thread_priority(0, false);
return 0; return SRSLTE_SUCCESS;
} else { } else {
return SRSLTE_ERROR_INVALID_INPUTS; return SRSLTE_ERROR_INVALID_INPUTS;
} }
@ -733,22 +801,8 @@ int rf_uhd_close(void* h)
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd_tx_metadata_free(&handler->tx_md); /// Free all made UHD objects
uhd_rx_metadata_free(&handler->rx_md_first); uhd_free(handler);
uhd_rx_metadata_free(&handler->rx_md);
#if HAVE_ASYNC_THREAD
if (handler->async_thread_running) {
handler->async_thread_running = false;
pthread_join(handler->async_thread, NULL);
}
#endif
uhd_tx_streamer_free(&handler->tx_stream);
uhd_rx_streamer_free(&handler->rx_stream);
uhd_usrp_free(&handler->usrp);
free(handler);
/** Something else to close the USRP?? */ /** Something else to close the USRP?? */
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
@ -1008,7 +1062,11 @@ int rf_uhd_send_timed(void* h,
bool is_start_of_burst, bool is_start_of_burst,
bool is_end_of_burst) bool is_end_of_burst)
{ {
void* _data[SRSLTE_MAX_PORTS] = {data, zero_mem, zero_mem, zero_mem}; // Maximum number of channels to NULL
void* _data[SRSLTE_MAX_CHANNELS] = {NULL};
// Set only first channel
_data[0] = data;
return rf_uhd_send_timed_multi( return rf_uhd_send_timed_multi(
h, _data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); h, _data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst);

View File

@ -100,7 +100,7 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_)
dev_name ? dev_name : "default", dev_name ? dev_name : "default",
device_args ? device_args : "default"); device_args ? device_args : "default");
if (srslte_rf_open_devname(&rf_device, dev_name, device_args, nof_channels)) { if (srslte_rf_open_devname(&rf_device, dev_name, device_args, nof_channels)) {
ERROR("Error opening RF device\n"); log_h->error("Error opening RF device\n");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }

View File

@ -358,7 +358,6 @@ void sync::run_thread()
sf_worker* worker = nullptr; sf_worker* worker = nullptr;
srslte_cell_t temp_cell = {}; srslte_cell_t temp_cell = {};
bool is_end_of_burst = false;
bool force_camping_sfn_sync = false; bool force_camping_sfn_sync = false;
srslte::rf_buffer_t dummy_buffer(sync_nof_rx_subframes); srslte::rf_buffer_t dummy_buffer(sync_nof_rx_subframes);
@ -514,8 +513,6 @@ void sync::run_thread()
} }
} }
is_end_of_burst = true;
// Start worker // Start worker
worker_com->semaphore.push(worker); worker_com->semaphore.push(worker);
workers_pool->start_worker(worker); workers_pool->start_worker(worker);
@ -535,7 +532,6 @@ void sync::run_thread()
Warning("SYNC: Out-of-sync detected in PSS/SSS\n"); Warning("SYNC: Out-of-sync detected in PSS/SSS\n");
out_of_sync(); out_of_sync();
worker->release(); worker->release();
is_end_of_burst = true;
// Force decoding MIB, for making sure that the TTI will be right // Force decoding MIB, for making sure that the TTI will be right
if (!force_camping_sfn_sync) { if (!force_camping_sfn_sync) {
@ -567,10 +563,7 @@ void sync::run_thread()
if (rx_time.frac_secs == 0 && rx_time.full_secs == 0) { if (rx_time.frac_secs == 0 && rx_time.full_secs == 0) {
usleep(1000); usleep(1000);
} }
if (is_end_of_burst) { radio_h->tx_end();
radio_h->tx_end();
is_end_of_burst = true;
}
} else { } else {
Debug("Sleeping\n"); Debug("Sleeping\n");
usleep(1000); usleep(1000);
@ -673,7 +666,7 @@ void sync::set_agc_enable(bool enable)
&ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain()); &ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain());
search_p.set_agc_enable(true); search_p.set_agc_enable(true);
} else { } else {
ERROR("Error: Radio does not provide RF information\n"); Error("Error: Radio does not provide RF information\n");
} }
} else { } else {
ERROR("Error setting AGC: PHY not initiated\n"); ERROR("Error setting AGC: PHY not initiated\n");