diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md index 376e59abafaae75d6e71baf49c75ee7a9e844837..170e9b61f865e6f9b62560f76784534f06212128 100644 --- a/common/config/DOC/config/devusage/api.md +++ b/common/config/DOC/config/devusage/api.md @@ -11,10 +11,16 @@ configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t init * if the bit CONFIG_ENABLECMDLINEONLY is set in `initflags` then the module allows parameters to be set only via the command line. This is used for the oai UE. ```c -void End_configmodule(void) +void end_configmodule(void) ``` -* Free memory which has been allocated by the configuration module since its initialization. +* Free memory which has been allocated by the configuration module for storing parameters values, when `PARAMFLAG_NOFREE` flag is not specified in the parameter definition. * Possibly calls the `config_<config source>_end` function +This call should be used when all configurations have been read. The program will still be able to use parameter values allocated by the config module WHEN THE `PARAMFLAG_NOFREE` flag has been specified in the parameter definition. The config module can be reloaded later in the program (not fully tested as not used today) + +```c +void free_configmodule(void) +``` +This call should be used to definitely free all resources allocated by the config module. All parameters values allocated by the config module become unavailable and no further reload of the config module are allowed. ## Retrieving parameter's values diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index fbc44c33635664c6cb2c9bf664fc4f56882bee02..922126b688759d76e87db501cdd537ec8db99439 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -250,46 +250,46 @@ configmodule_interface_t *load_configmodule(int argc, modeparams=cfgmode; cfgmode=strdup(CONFIG_LIBCONFIGFILE); } - - cfgptr = calloc(sizeof(configmodule_interface_t),1); + if (cfgptr == NULL) { + cfgptr = calloc(sizeof(configmodule_interface_t),1); /* argv_info is used to memorize command line options which have been recognized */ /* and to detect unrecognized command line options which might have been specified */ - cfgptr->argv_info = calloc(sizeof(int32_t), argc+10); + cfgptr->argv_info = calloc(sizeof(int32_t), argc+10); /* argv[0] is the exec name, always Ok */ - cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; + cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; /* when OoptIdx is >0, -O option has been detected at position OoptIdx * we must memorize arv[OoptIdx is Ok */ - if (OoptIdx >= 0) { - cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; - cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; - } + if (OoptIdx >= 0) { + cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; + cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; + } - cfgptr->rtflags = cfgptr->rtflags | tmpflags; - cfgptr->argc = argc; - cfgptr->argv = argv; - cfgptr->cfgmode=strdup(cfgmode); - cfgptr->num_cfgP=0; - atoken=strtok_r(modeparams,":",&strtokctx); + cfgptr->rtflags = cfgptr->rtflags | tmpflags; + cfgptr->argc = argc; + cfgptr->argv = argv; + cfgptr->cfgmode=strdup(cfgmode); + cfgptr->num_cfgP=0; + atoken=strtok_r(modeparams,":",&strtokctx); - while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { + while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { /* look for debug level in the config parameters, it is common to all config mode and will be removed from the parameter array passed to the shared module */ - char *aptr; - aptr=strcasestr(atoken,"dbgl"); + char *aptr; + aptr=strcasestr(atoken,"dbgl"); + + if (aptr != NULL) { + cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0); + } else { + cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken); + cfgptr->num_cfgP++; + } - if (aptr != NULL) { - cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0); - } else { - cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken); - cfgptr->num_cfgP++; + atoken = strtok_r(NULL,":",&strtokctx); } - atoken = strtok_r(NULL,":",&strtokctx); + printf("[CONFIG] get parameters from %s ",cfgmode); } - - printf("[CONFIG] get parameters from %s ",cfgmode); - for (i=0; i<cfgptr->num_cfgP; i++) { printf("%s ",cfgptr->cfgP[i]); } @@ -339,6 +339,7 @@ void end_configmodule(void) { pthread_mutex_lock(&cfgptr->memBlocks_mutex); printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); + int n=0; for(int i=0; i<cfgptr->numptrs ; i++) { if (cfgptr->oneBlock[i].ptrs != NULL && cfgptr->oneBlock[i].ptrsAllocated== true && cfgptr->oneBlock[i].toFree) { free(cfgptr->oneBlock[i].ptrs); @@ -358,13 +359,23 @@ void free_configmodule(void) { end_configmodule(); if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); - - printf ("[CONFIG] free %i config parameter pointers\n",cfgptr->num_cfgP); + int n=0; + for(int i=0; i<cfgptr->numptrs ; i++) { + if (cfgptr->ptrs[i] != NULL) { + free(cfgptr->ptrs[i]); + cfgptr->ptrs[i]=NULL; + cfgptr->ptrsAllocated[i] = false; + n++; + } + } + printf ("[CONFIG] %u/%u persistent config value pointers have been released\n",n,cfgptr->numptrs); + cfgptr->numptrs=0; + printf ("[CONFIG] free %i config module parameter pointers\n",cfgptr->num_cfgP); for (int i=0; i<cfgptr->num_cfgP; i++) { if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); } - + free(cfgptr->argv_info); free(cfgptr); cfgptr=NULL; } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index e3814994ad4a1b5e9bdf7f5c9c0b88f8d3fe89e7..249ef6be5bd198f73874544674ef13b8c566d630 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -120,7 +120,15 @@ extern configmodule_interface_t *cfgptr; #define CONFIG_ENABLECMDLINEONLY (1<<1) extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags); +/* free ressources used to read parameters, keep memory + * allocated for parameters values which has been defined with the PARAMFLAG_NOFREE flag + * should be used as soon as there is no need to read parameters but doesn't prevent + * a new config module init +*/ extern void end_configmodule(void); +/* free all config module memory, to be used at end of program as + * it will free parameters values even those specified with the PARAMFLAG_NOFREE flag */ +extern void free_configmodule(void); #define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n"); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 39cd5407955400f69478c7cd2e7717ba5bc1515c..9632c48208647edf2a5079d5b1f35c575634d26f 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -658,10 +658,15 @@ int main(int argc, char **argv) if (ouput_vcd) vcd_signal_dumper_close(); - - loader_reset(); - logTerm(); - - return (n_errors); + end_configmodule(); + if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) { + exit_fun("[NR_DLSCHSIM] Error, configuration module init 2 failed\n"); + } + logInit(); + loader_reset(); + logTerm(); + free_configmodule(); + + return (n_errors); }