Fix duplicated memory allocation when replaying using mmap,
add use_mmap parameter for the record player device fix assertion when replaying without using mmap
This commit is contained in:
@@ -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
|
// Use mmap for IQ files for systems with less than 6GB total RAM
|
||||||
sysinfo(&systeminfo);
|
sysinfo(&systeminfo);
|
||||||
|
|
||||||
if (systeminfo.totalram < 6144000000) {
|
if (systeminfo.totalram < 6144000000 && ((*recplay_conf)->use_mmap == 1)) {
|
||||||
(*recplay_state)->use_mmap = 0;
|
LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9);
|
||||||
} else {
|
(*recplay_conf)->use_mmap = 0;
|
||||||
(*recplay_state)->use_mmap = 1;
|
|
||||||
}
|
}
|
||||||
} else { /* record player enabled */
|
} else { /* record player enabled */
|
||||||
free(*recplay_conf);
|
free(*recplay_conf);
|
||||||
|
|||||||
@@ -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_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_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_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 */
|
/* 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_FILE "subframes-file"
|
||||||
#define CONFIG_OPT_SF_REC "subframes-record"
|
#define CONFIG_OPT_SF_REC "subframes-record"
|
||||||
@@ -87,7 +87,7 @@ typedef struct {
|
|||||||
#define CONFIG_OPT_SF_LOOPS "subframes-loops"
|
#define CONFIG_OPT_SF_LOOPS "subframes-loops"
|
||||||
#define CONFIG_OPT_SF_RDELAY "subframes-read-delay"
|
#define CONFIG_OPT_SF_RDELAY "subframes-read-delay"
|
||||||
#define CONFIG_OPT_SF_WDELAY "subframes-write-delay"
|
#define CONFIG_OPT_SF_WDELAY "subframes-write-delay"
|
||||||
|
#define CONFIG_OPT_USE_MMAP "use-mmap"
|
||||||
#define DEVICE_RECPLAY_SECTION "device.recplay"
|
#define DEVICE_RECPLAY_SECTION "device.recplay"
|
||||||
/* For information only - the macro is not usable in C++ */
|
/* For information only - the macro is not usable in C++ */
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
@@ -95,13 +95,14 @@ typedef struct {
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define DEVICE_RECPLAY_PARAMS_DESC { \
|
#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_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_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_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_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_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_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_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 */
|
}/*! \brief Record Player Configuration and state */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char u_sf_filename[1024]; // subframes file path
|
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_loops ; // number of loops in replay mode
|
||||||
unsigned int u_sf_read_delay; // read delay 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 u_sf_write_delay ; // write delay in replay mode
|
||||||
|
unsigned int use_mmap; // default is to use mmap
|
||||||
} recplay_conf_t;
|
} recplay_conf_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int use_mmap; // default is to use mmap
|
|
||||||
size_t mapsize;
|
size_t mapsize;
|
||||||
FILE *pFile;
|
FILE *pFile;
|
||||||
int fd;
|
int fd;
|
||||||
|
|||||||
@@ -68,19 +68,18 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->use_mmap) {
|
if (c->use_mmap) {
|
||||||
// use mmap
|
// use mmap
|
||||||
s->mapsize=sb.st_size;
|
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 );
|
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) ;
|
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) {
|
if (mptr != MAP_FAILED) {
|
||||||
|
s->ms_sample = (iqrec_t *) ( mptr + sizeof(iqfile_header_t));
|
||||||
parse_iqfile_header(device, (iqfile_header_t *)mptr);
|
parse_iqfile_header(device, (iqfile_header_t *)mptr);
|
||||||
s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t));
|
s->ms_sample = (iqrec_t *)((char *)mptr + sizeof(iqfile_header_t));
|
||||||
LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks );
|
LOG_I(HW,"Loaded %u subframes.\n",s->nbSamplesBlocks );
|
||||||
} else {
|
} else {
|
||||||
LOG_E(HW,"Cannot mmap file, exiting.\n");
|
LOG_E(HW,"Cannot mmap file, exiting, errnor %s\n",strerror(errno));
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
exit(-1);
|
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) {
|
if (lseek(s->fd,sizeof(iqfile_header_t), SEEK_SET) == 0) {
|
||||||
LOG_I(HW,"Initial seek at beginning of the file\n" );
|
LOG_I(HW,"Initial seek at beginning of the file\n" );
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
LOG_E(HW,"Cannot read header in %s exiting.\n",c->u_sf_filename );
|
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) {
|
static void trx_iqplayer_end(openair0_device *device) {
|
||||||
if (device == NULL)
|
if (device == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (device->recplay_state == NULL)
|
if (device->recplay_state == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (device->recplay_state->use_mmap) {
|
if (device->openair0_cfg->recplay_conf->use_mmap) {
|
||||||
if (device->recplay_state->ms_sample != MAP_FAILED) {
|
if (device->recplay_state->ms_sample != MAP_FAILED) {
|
||||||
munmap(device->recplay_state->ms_sample, device->recplay_state->mapsize);
|
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");
|
LOG_I(HW,"go back at the beginning of IQ file");
|
||||||
device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
|
device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
|
||||||
|
|
||||||
if (!s->use_mmap) {
|
if (!(device->openair0_cfg->recplay_conf->use_mmap) ) {
|
||||||
if (lseek(device->recplay_state->fd, 0, SEEK_SET) != 0) {
|
close(device->recplay_state->fd);
|
||||||
LOG_E(HW, "Problem seeking at the beginning of IQ file");
|
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
|
// read sample from file
|
||||||
if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
|
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);
|
exit(-1);
|
||||||
} else {
|
} else {
|
||||||
if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) != s->ms_sample->nbBytes) {
|
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);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +224,9 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes
|
|||||||
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
|
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
|
||||||
// the current timestamp is the stored timestamp until we wrap on input
|
// the current timestamp is the stored timestamp until we wrap on input
|
||||||
// USRP shifts 1 sample time to time
|
// 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,"");
|
AssertFatal(nsamps*4==curHeader->nbBytes,"");
|
||||||
*ptimestamp = s->currentTs;
|
*ptimestamp = s->currentTs;
|
||||||
memcpy(buff[0], curHeader+1, nsamps*4);
|
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
|
// Prepare for next read
|
||||||
s->currentTs+=nsamps;
|
s->currentTs+=nsamps;
|
||||||
|
|
||||||
if (s->use_mmap)
|
if (device->openair0_cfg->recplay_conf->use_mmap)
|
||||||
s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes;
|
s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes;
|
||||||
|
|
||||||
struct timespec req;
|
struct timespec req;
|
||||||
|
|||||||
Reference in New Issue
Block a user