Skip to content

Commit

Permalink
core: High Performance Memory Allocator included
Browse files Browse the repository at this point in the history
	* ideal for systems with high volumes of calls-per-second
	* fine-grained locking
	* tunable two-level hashing of free memory fragments
	* memory allocation pattern recording
	* fragmentation-on-startup
	* enable "HP_MALLOC" within "make menuconfig"
  • Loading branch information
liviuchircu committed Mar 20, 2014
1 parent 5fbc82f commit 56b325b
Show file tree
Hide file tree
Showing 17 changed files with 1,652 additions and 81 deletions.
1 change: 1 addition & 0 deletions Makefile.conf.template
Expand Up @@ -64,6 +64,7 @@ DEFS+= -DDISABLE_NAGLE #Disabled the TCP NAgle Algorithm ( lower delay )
DEFS+= -DSTATISTICS #Enables the statistics manager
DEFS+= -DCHANGEABLE_DEBUG_LEVEL #Enables support for changeable debug level at runtime
DEFS+= -DHAVE_RESOLV_RES #Support for changing some of the resolver parameters
DEFS+= -DHP_MALLOC #High performance allocator with fine-grained locking
DEFS+= -DF_MALLOC #An even faster allocator. Not recommended for debugging
DEFS+= -DUSE_TCP #Compiles in TCP support
#DEFS+= -DUSE_TLS #Compiles in TLS support
Expand Down
4 changes: 4 additions & 0 deletions cfg.lex
Expand Up @@ -302,6 +302,8 @@ PORT port
MAXBUFFER maxbuffer
CHILDREN children
CHECK_VIA check_via
SHM_HASH_SPLIT_PERCENTAGE "shm_hash_split_percentage"
SHM_SECONDARY_HASH_SIZE "shm_secondary_hash_size"
MEMLOG "memlog"|"mem_log"
MEMDUMP "memdump"|"mem_dump"
EXECMSGTHRESHOLD "execmsgthreshold"|"exec_msg_threshold"
Expand Down Expand Up @@ -607,6 +609,8 @@ IMPORTFILE "import_file"
<INITIAL>{MAXBUFFER} { count(); yylval.strval=yytext; return MAXBUFFER; }
<INITIAL>{CHILDREN} { count(); yylval.strval=yytext; return CHILDREN; }
<INITIAL>{CHECK_VIA} { count(); yylval.strval=yytext; return CHECK_VIA; }
<INITIAL>{SHM_HASH_SPLIT_PERCENTAGE} { count(); yylval.strval=yytext; return SHM_HASH_SPLIT_PERCENTAGE; }
<INITIAL>{SHM_SECONDARY_HASH_SIZE} { count(); yylval.strval=yytext; return SHM_SECONDARY_HASH_SIZE; }
<INITIAL>{MEMLOG} { count(); yylval.strval=yytext; return MEMLOG; }
<INITIAL>{MEMDUMP} { count(); yylval.strval=yytext; return MEMDUMP; }
<INITIAL>{EXECMSGTHRESHOLD} { count(); yylval.strval=yytext; return EXECMSGTHRESHOLD; }
Expand Down
6 changes: 6 additions & 0 deletions cfg.y
Expand Up @@ -327,6 +327,8 @@ extern int line;
%token PORT
%token CHILDREN
%token CHECK_VIA
%token SHM_HASH_SPLIT_PERCENTAGE
%token SHM_SECONDARY_HASH_SIZE
%token MEMLOG
%token MEMDUMP
%token EXECMSGTHRESHOLD
Expand Down Expand Up @@ -689,6 +691,10 @@ assign_stm: DEBUG EQUAL snumber {
| CHILDREN EQUAL error { yyerror("number expected"); }
| CHECK_VIA EQUAL NUMBER { check_via=$3; }
| CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
| SHM_HASH_SPLIT_PERCENTAGE EQUAL NUMBER { shm_hash_split_percentage=$3; }
| SHM_HASH_SPLIT_PERCENTAGE EQUAL error { yyerror("number expected"); }
| SHM_SECONDARY_HASH_SIZE EQUAL NUMBER { shm_secondary_hash_size=$3; }
| SHM_SECONDARY_HASH_SIZE EQUAL error { yyerror("number expected"); }
| MEMLOG EQUAL NUMBER { memlog=$3; memdump=$3; }
| MEMLOG EQUAL error { yyerror("int value expected"); }
| MEMDUMP EQUAL NUMBER { memdump=$3; }
Expand Down
5 changes: 5 additions & 0 deletions config.h
Expand Up @@ -41,6 +41,8 @@
#define SIPS_PORT 5061 /*! default sip port for tls if none specified */

#define CFG_FILE CFG_DIR "opensips.cfg"
#define MEM_WARMING_DEFAULT_PATTERN_FILE CFG_DIR "mem_warming_pattern"
#define MEM_WARMING_DEFAULT_PERCENTAGE 85

#define TLS_PKEY_FILE CFG_DIR "tls/cert.pem"
#define TLS_CERT_FILE CFG_DIR "tls/cert.pem"
Expand Down Expand Up @@ -119,6 +121,9 @@

#define PKG_MEM_SIZE 2 /*!< Used only if PKG_MALLOC is defined*/
#define SHM_MEM_SIZE 32 /*!< Used if SH_MEM is defined*/
#define SHM_MAX_SECONDARY_HASH_SIZE 100
#define DEFAULT_SHM_HASH_SPLIT_PERCENTAGE 1 /*!< Used if SH_MEM is defined*/
#define DEFAULT_SHM_SECONDARY_HASH_SIZE 8

#define TIMER_TICK 1 /*!< one second */
#define UTIMER_TICK 100*1000 /*!< 100 miliseconds*/
Expand Down
6 changes: 6 additions & 0 deletions globals.h
Expand Up @@ -127,7 +127,13 @@ extern int disable_dns_blacklist;
extern int cfg_errors;

extern unsigned long shm_mem_size;
extern unsigned int shm_hash_split_percentage;
extern unsigned int shm_hash_split_factor;
extern unsigned int shm_secondary_hash_size;
extern unsigned long pkg_mem_size;
extern char *mem_warming_pattern_file;
extern int mem_warming_percentage;
extern int mem_warming_enabled;

extern int reply_to_via;

Expand Down
48 changes: 39 additions & 9 deletions main.c
Expand Up @@ -336,10 +336,26 @@ time_t startup_time = 0;

/* shared memory (in MB) */
unsigned long shm_mem_size=SHM_MEM_SIZE * 1024 * 1024;
unsigned int shm_hash_split_percentage = DEFAULT_SHM_HASH_SPLIT_PERCENTAGE;
unsigned int shm_secondary_hash_size = DEFAULT_SHM_SECONDARY_HASH_SIZE;

/* shared memory (in MB) */
/* packaged memory (in MB) */
unsigned long pkg_mem_size=PKG_MEM_SIZE * 1024 * 1024;

/*
* adaptive image of OpenSIPS's memory usage during runtime
* used to fragment the shared memory pool at daemon startup
*/
char *mem_warming_pattern_file;
int mem_warming_enabled = 1;

/*
* percentage of shared memory which will be fragmented at startup
* values between [0, 75]
*/
int mem_warming_percentage = -1;


/* export command-line to anywhere else */
int my_argc;
char **my_argv;
Expand All @@ -362,10 +378,22 @@ void cleanup(int show_status)
{
LM_INFO("cleanup\n");
/*clean-up*/

/* hack: force-unlock the shared memory lock in case
some process crashed and let it locked; this will
allow an almost gracious shutdown */
if (mem_lock)
shm_unlock(); /* hack: force-unlock the shared memory lock in case
some process crashed and let it locked; this will
allow an almost gracious shutdown */
#ifdef HP_MALLOC
{
int i;

for (i = 0; i < F_HASH_SIZE; i++)
shm_unlock(i);
}
#else
shm_unlock();
#endif

handle_ql_shutdown();
destroy_modules();
#ifdef USE_TCP
Expand Down Expand Up @@ -1438,6 +1466,13 @@ int main(int argc, char** argv)
* --andrei */
if (init_shm_mallocs()==-1)
goto error;

/* Init statistics */
if (init_stats_collector()<0) {
LM_ERR("failed to initialize statistics\n");
goto error;
}

/*init timer, before parsing the cfg!*/
if (init_timer()<0){
LM_CRIT("could not initialize timer, exiting...\n");
Expand Down Expand Up @@ -1512,11 +1547,6 @@ int main(int argc, char** argv)
LM_ERR("failed to initialize serialization\n");
goto error;
}
/* Init statistics */
if (init_stats_collector()<0) {
LM_ERR("failed to initialize statistics\n");
goto error;
}
/* Init MI */
if (init_mi_core()<0) {
LM_ERR("failed to initialize MI core\n");
Expand Down
5 changes: 4 additions & 1 deletion mem/f_malloc.c
Expand Up @@ -155,9 +155,12 @@ static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag)
(*f)->prev = &(frag->u.nxt_free);

*f=frag;

#if defined(DBG_F_MALLOC) || defined(STATISTICS)
qm->free_hash[hash].no++;
free_plus(qm , frag->size);
#endif

free_plus(qm, frag->size);
}

static inline void fm_remove_free(struct fm_block* qm, struct fm_frag* n)
Expand Down

0 comments on commit 56b325b

Please sign in to comment.