From a1aae8292513672f3637bcc06db2baa279a489e8 Mon Sep 17 00:00:00 2001 From: alblf Date: Fri, 18 Feb 2022 18:22:14 +0100 Subject: [PATCH] Fix duplicated memory allocation when replaying using mmap, add use_mmap parameter for the record player device fix assertion when replaying without using mmap --- targets/ARCH/COMMON/record_player.c | 7 +++--- targets/ARCH/COMMON/record_player.h | 13 ++++++----- targets/ARCH/iqplayer/iqplayer_lib.c | 33 ++++++++++++++-------------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/targets/ARCH/COMMON/record_player.c b/targets/ARCH/COMMON/record_player.c index 522f6b6d16..37f985b6b2 100644 --- a/targets/ARCH/COMMON/record_player.c +++ b/targets/ARCH/COMMON/record_player.c @@ -58,10 +58,9 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_ // Use mmap for IQ files for systems with less than 6GB total RAM sysinfo(&systeminfo); - if (systeminfo.totalram < 6144000000) { - (*recplay_state)->use_mmap = 0; - } else { - (*recplay_state)->use_mmap = 1; + if (systeminfo.totalram < 6144000000 && ((*recplay_conf)->use_mmap == 1)) { + LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9); + (*recplay_conf)->use_mmap = 0; } } else { /* record player enabled */ free(*recplay_conf); diff --git a/targets/ARCH/COMMON/record_player.h b/targets/ARCH/COMMON/record_player.h index d91da68323..9310355e5b 100644 --- a/targets/ARCH/COMMON/record_player.h +++ b/targets/ARCH/COMMON/record_player.h @@ -78,7 +78,7 @@ typedef struct { #define CONFIG_HLP_SF_LOOPS "Number of loops to replay of the entire subframes file" #define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode" #define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode" - +#define CONFIG_HLP_USE_MMAP "In replay mode, map iq file in memory before replaying" /* keyword strings for config options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_OPT_SF_FILE "subframes-file" #define CONFIG_OPT_SF_REC "subframes-record" @@ -87,7 +87,7 @@ typedef struct { #define CONFIG_OPT_SF_LOOPS "subframes-loops" #define CONFIG_OPT_SF_RDELAY "subframes-read-delay" #define CONFIG_OPT_SF_WDELAY "subframes-write-delay" - +#define CONFIG_OPT_USE_MMAP "use-mmap" #define DEVICE_RECPLAY_SECTION "device.recplay" /* For information only - the macro is not usable in C++ */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -95,13 +95,14 @@ typedef struct { /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define DEVICE_RECPLAY_PARAMS_DESC { \ - {CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 1024}, \ - {CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \ - {CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:(char **)((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 1024}, \ + {CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \ + {CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \ {CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \ + {CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \ }/*! \brief Record Player Configuration and state */ typedef struct { char u_sf_filename[1024]; // subframes file path @@ -109,10 +110,10 @@ typedef struct { unsigned int u_sf_loops ; // number of loops in replay mode unsigned int u_sf_read_delay; // read delay in replay mode unsigned int u_sf_write_delay ; // write delay in replay mode + unsigned int use_mmap; // default is to use mmap } recplay_conf_t; typedef struct { - int use_mmap; // default is to use mmap size_t mapsize; FILE *pFile; int fd; diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index 8b6844f9d3..b62c1935d3 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -68,19 +68,18 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair exit(-1); } - if (s->use_mmap) { + if (c->use_mmap) { // use mmap s->mapsize=sb.st_size; LOG_I(HW,"Loading subframes using mmap() from %s size=%lu bytes ...\n",c->u_sf_filename, (uint64_t)sb.st_size ); void *mptr = mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) ; - s->ms_sample = (iqrec_t *) ( mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, s->fd, 0) + sizeof(iqfile_header_t)); - if (mptr != MAP_FAILED) { + s->ms_sample = (iqrec_t *) ( mptr + sizeof(iqfile_header_t)); parse_iqfile_header(device, (iqfile_header_t *)mptr); s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t)); LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks ); } else { - LOG_E(HW,"Cannot mmap file, exiting.\n"); + LOG_E(HW,"Cannot mmap file, exiting, errnor %s\n",strerror(errno)); close(s->fd); exit(-1); } @@ -108,7 +107,7 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair if (lseek(s->fd,sizeof(iqfile_header_t), SEEK_SET) == 0) { LOG_I(HW,"Initial seek at beginning of the file\n" ); } else { - LOG_I(HW,"Problem initial seek at beginning of the file\n"); + LOG_I(HW,"Problem initial seek at beginning of the file, %s\n",strerror(errno)); } } else { LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename ); @@ -134,11 +133,10 @@ static int trx_iqplayer_start(openair0_device *device) { static void trx_iqplayer_end(openair0_device *device) { if (device == NULL) return; - if (device->recplay_state == NULL) return; - if (device->recplay_state->use_mmap) { + if (device->openair0_cfg->recplay_conf->use_mmap) { if (device->recplay_state->ms_sample != MAP_FAILED) { munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize); } @@ -201,21 +199,22 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes LOG_I(HW,"go back at the beginning of IQ file"); device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample; - if (!s->use_mmap) { - if (lseek(device->recplay_state->fd, 0, SEEK_SET) != 0) { - LOG_E(HW, "Problem seeking at the beginning of IQ file"); - } + if (!(device->openair0_cfg->recplay_conf->use_mmap) ) { + close(device->recplay_state->fd); + iqplayer_loadfile(device, device->openair0_cfg); + // LOG_E(HW, "Problem seeking at the beginning of IQ file %s\n",strerror(errno)); + } } - if (!s->use_mmap) { + if (!(device->openair0_cfg->recplay_conf->use_mmap)) { // read sample from file if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) { - LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock ); + LOG_E(HW,"pb reading iqfile at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) ); exit(-1); } else { if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) != s->ms_sample->nbBytes) { - LOG_E(HW,"pb reading iqfile at index %lu\n",sizeof(iqrec_t)*s->curSamplesBlock ); + LOG_E(HW,"pb reading iqfile at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) ); exit(-1); } } @@ -225,7 +224,9 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" ); // the current timestamp is the stored timestamp until we wrap on input // USRP shifts 1 sample time to time - AssertFatal(s->wrap_count !=0 || abs(curHeader->ts-s->currentTs) < 5 ,""); + if (s->wrap_count !=0 && device->openair0_cfg->recplay_conf->use_mmap) + AssertFatal( abs(curHeader->ts-s->currentTs) < 5 , + "wrap_count=%li, ts %lu %lu",s->wrap_count,curHeader->ts,s->currentTs); AssertFatal(nsamps*4==curHeader->nbBytes,""); *ptimestamp = s->currentTs; memcpy(buff[0], curHeader+1, nsamps*4); @@ -233,7 +234,7 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes // Prepare for next read s->currentTs+=nsamps; - if (s->use_mmap) + if (device->openair0_cfg->recplay_conf->use_mmap) s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes; struct timespec req;