- better control over existing code for joining free memory fragments
- existing QM_JOIN_FREE renamed to MEM_JOIN_FREE - to be used in other
memory managers than q_malloc
- new cfg parameter mem_join - if set to 1, q_malloc does join of free
memory fragments. default is 0. in use if MEM_JOIN_FREE is defined
... | ... |
@@ -560,6 +560,8 @@ data_target = $(prefix)/$(data_dir) |
560 | 560 |
# now. |
561 | 561 |
# -DDBG_MALLOC |
562 | 562 |
# issues additional debugging information if lock/unlock is called |
563 |
+# -DMEM_JOIN_FREE |
|
564 |
+# enable the join of free memory chunks (see also mem_join cfg param) |
|
563 | 565 |
# -DFAST_LOCK |
564 | 566 |
# uses fast arhitecture specific locking (see the arh. specific section) |
565 | 567 |
# -DUSE_SYSV_SEM |
... | ... |
@@ -704,6 +706,7 @@ C_DEFS= $(extra_defs) \ |
704 | 704 |
|
705 | 705 |
ifeq ($(MEMDBG), 1) |
706 | 706 |
C_DEFS+= -DDBG_QM_MALLOC |
707 |
+ C_DEFS+= -DMEM_JOIN_FREE |
|
707 | 708 |
else |
708 | 709 |
C_DEFS+= -DF_MALLOC |
709 | 710 |
endif |
... | ... |
@@ -398,7 +398,8 @@ SYN_BRANCH syn_branch |
398 | 398 |
MEMLOG "memlog"|"mem_log" |
399 | 399 |
MEMDBG "memdbg"|"mem_dbg" |
400 | 400 |
MEMSUM "mem_summary" |
401 |
-MEMSAFETY "mem_safety" |
|
401 |
+MEMSAFETY "mem_safety" |
|
402 |
+MEMJOIN "mem_join" |
|
402 | 403 |
CORELOG "corelog"|"core_log" |
403 | 404 |
SIP_WARNING sip_warning |
404 | 405 |
SERVER_SIGNATURE server_signature |
... | ... |
@@ -799,6 +800,7 @@ IMPORTFILE "import_file" |
799 | 799 |
<INITIAL>{MEMDBG} { count(); yylval.strval=yytext; return MEMDBG; } |
800 | 800 |
<INITIAL>{MEMSUM} { count(); yylval.strval=yytext; return MEMSUM; } |
801 | 801 |
<INITIAL>{MEMSAFETY} { count(); yylval.strval=yytext; return MEMSAFETY; } |
802 |
+<INITIAL>{MEMJOIN} { count(); yylval.strval=yytext; return MEMJOIN; } |
|
802 | 803 |
<INITIAL>{CORELOG} { count(); yylval.strval=yytext; return CORELOG; } |
803 | 804 |
<INITIAL>{SIP_WARNING} { count(); yylval.strval=yytext; return SIP_WARNING; } |
804 | 805 |
<INITIAL>{USER} { count(); yylval.strval=yytext; return USER; } |
... | ... |
@@ -453,6 +453,7 @@ extern char *finame; |
453 | 453 |
%token MEMDBG |
454 | 454 |
%token MEMSUM |
455 | 455 |
%token MEMSAFETY |
456 |
+%token MEMJOIN |
|
456 | 457 |
%token CORELOG |
457 | 458 |
%token SIP_WARNING |
458 | 459 |
%token SERVER_SIGNATURE |
... | ... |
@@ -962,6 +963,8 @@ assign_stm: |
962 | 962 |
| MEMSUM EQUAL error { yyerror("int value expected"); } |
963 | 963 |
| MEMSAFETY EQUAL intno { default_core_cfg.mem_safety=$3; } |
964 | 964 |
| MEMSAFETY EQUAL error { yyerror("int value expected"); } |
965 |
+ | MEMJOIN EQUAL intno { default_core_cfg.mem_join=$3; } |
|
966 |
+ | MEMJOIN EQUAL error { yyerror("int value expected"); } |
|
965 | 967 |
| CORELOG EQUAL intno { default_core_cfg.corelog=$3; } |
966 | 968 |
| CORELOG EQUAL error { yyerror("int value expected"); } |
967 | 969 |
| SIP_WARNING EQUAL NUMBER { sip_warning=$3; } |
... | ... |
@@ -122,6 +122,7 @@ struct cfg_group_core default_core_cfg = { |
122 | 122 |
3, /*!< mem_summary -flags: 0 off, 1 pkg_status, 2 shm_status, |
123 | 123 |
4 pkg_sums, 8 shm_sums, 16 short_status */ |
124 | 124 |
0, /*!< mem_safety - 0 disabled */ |
125 |
+ 0, /*!< mem_join - 0 disabled */ |
|
125 | 126 |
L_ERR, /*!< corelog */ |
126 | 127 |
L_ERR, /*!< latency log */ |
127 | 128 |
0, /*!< latency limit db */ |
... | ... |
@@ -315,6 +316,8 @@ cfg_def_t core_cfg_def[] = { |
315 | 315 |
" 16 - short status instead of dump" }, |
316 | 316 |
{"mem_safety", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, |
317 | 317 |
"safety level for memory operations"}, |
318 |
+ {"mem_join", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, |
|
319 |
+ "join free memory fragments"}, |
|
318 | 320 |
{"corelog", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, |
319 | 321 |
"log level for non-critical core error messages"}, |
320 | 322 |
{"latency_log", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, |
... | ... |
@@ -109,6 +109,7 @@ struct cfg_group_core { |
109 | 109 |
int memlog; /*!< log level for memory status/summary info */ |
110 | 110 |
int mem_summary; /*!< display memory status/summary info on exit */ |
111 | 111 |
int mem_safety; /*!< memory safety control option */ |
112 |
+ int mem_join; /*!< memory free fragments join option */ |
|
112 | 113 |
int corelog; /*!< log level for non-critcal core error messages */ |
113 | 114 |
int latency_log; /*!< log level for latency limits messages */ |
114 | 115 |
int latency_limit_db; /*!< alert limit of running db commands */ |
... | ... |
@@ -428,10 +428,10 @@ void qm_free(struct qm_block* qm, void* p) |
428 | 428 |
{ |
429 | 429 |
struct qm_frag* f; |
430 | 430 |
unsigned long size; |
431 |
-#ifdef QM_JOIN_FREE |
|
431 |
+#ifdef MEM_JOIN_FREE |
|
432 | 432 |
struct qm_frag* next; |
433 | 433 |
struct qm_frag* prev; |
434 |
-#endif /* QM_JOIN_FREE*/ |
|
434 |
+#endif /* MEM_JOIN_FREE*/ |
|
435 | 435 |
|
436 | 436 |
#ifdef DBG_QM_MALLOC |
437 | 437 |
MDBG("qm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); |
... | ... |
@@ -446,9 +446,6 @@ void qm_free(struct qm_block* qm, void* p) |
446 | 446 |
LOG(L_WARN, "WARNING:qm_free: free(0) called\n"); |
447 | 447 |
return; |
448 | 448 |
} |
449 |
-#ifdef QM_JOIN_FREE |
|
450 |
- next=prev=0; |
|
451 |
-#endif /* QM_JOIN_FREE*/ |
|
452 | 449 |
f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag)); |
453 | 450 |
#ifdef DBG_QM_MALLOC |
454 | 451 |
qm_debug_frag(qm, f); |
... | ... |
@@ -470,43 +467,46 @@ void qm_free(struct qm_block* qm, void* p) |
470 | 470 |
sr_event_exec(SREV_PKG_SET_REAL_USED, (void*)qm->real_used); |
471 | 471 |
#endif |
472 | 472 |
|
473 |
-#ifdef QM_JOIN_FREE |
|
474 |
- /* mark this fragment as used (might fall into the middle of joined frags) |
|
475 |
- to give us an extra chance of detecting a double free call (if the joined |
|
476 |
- fragment has not yet been reused) */ |
|
477 |
- f->u.nxt_free=(void*)0x1L; /* bogus value, just to mark it as free */ |
|
478 |
- /* join packets if possible*/ |
|
479 |
- next=FRAG_NEXT(f); |
|
480 |
- if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){ |
|
473 |
+#ifdef MEM_JOIN_FREE |
|
474 |
+ if(unlikely(cfg_get(core, core_cfg, mem_join)!=0)) { |
|
475 |
+ next=prev=0; |
|
476 |
+ /* mark this fragment as used (might fall into the middle of joined frags) |
|
477 |
+ to give us an extra chance of detecting a double free call (if the joined |
|
478 |
+ fragment has not yet been reused) */ |
|
479 |
+ f->u.nxt_free=(void*)0x1L; /* bogus value, just to mark it as free */ |
|
480 |
+ /* join packets if possible*/ |
|
481 |
+ next=FRAG_NEXT(f); |
|
482 |
+ if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){ |
|
481 | 483 |
/* join */ |
482 | 484 |
#ifdef DBG_QM_MALLOC |
483 |
- qm_debug_frag(qm, next); |
|
485 |
+ qm_debug_frag(qm, next); |
|
484 | 486 |
#endif |
485 |
- qm_detach_free(qm, next); |
|
486 |
- size+=next->size+FRAG_OVERHEAD; |
|
487 |
- qm->real_used-=FRAG_OVERHEAD; |
|
488 |
- qm->free_hash[GET_HASH(next->size)].no--; /* FIXME slow */ |
|
489 |
- } |
|
487 |
+ qm_detach_free(qm, next); |
|
488 |
+ size+=next->size+FRAG_OVERHEAD; |
|
489 |
+ qm->real_used-=FRAG_OVERHEAD; |
|
490 |
+ qm->free_hash[GET_HASH(next->size)].no--; /* FIXME slow */ |
|
491 |
+ } |
|
490 | 492 |
|
491 |
- if (f > qm->first_frag){ |
|
492 |
- prev=FRAG_PREV(f); |
|
493 |
- /* (struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f- |
|
493 |
+ if (f > qm->first_frag){ |
|
494 |
+ prev=FRAG_PREV(f); |
|
495 |
+ /* (struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f- |
|
494 | 496 |
sizeof(struct qm_frag_end))->size);*/ |
495 | 497 |
#ifdef DBG_QM_MALLOC |
496 |
- qm_debug_frag(qm, prev); |
|
498 |
+ qm_debug_frag(qm, prev); |
|
497 | 499 |
#endif |
498 |
- if (prev->u.is_free){ |
|
499 |
- /*join*/ |
|
500 |
- qm_detach_free(qm, prev); |
|
501 |
- size+=prev->size+FRAG_OVERHEAD; |
|
502 |
- qm->real_used-=FRAG_OVERHEAD; |
|
503 |
- qm->free_hash[GET_HASH(prev->size)].no--; /* FIXME slow */ |
|
504 |
- f=prev; |
|
500 |
+ if (prev->u.is_free){ |
|
501 |
+ /*join*/ |
|
502 |
+ qm_detach_free(qm, prev); |
|
503 |
+ size+=prev->size+FRAG_OVERHEAD; |
|
504 |
+ qm->real_used-=FRAG_OVERHEAD; |
|
505 |
+ qm->free_hash[GET_HASH(prev->size)].no--; /* FIXME slow */ |
|
506 |
+ f=prev; |
|
507 |
+ } |
|
505 | 508 |
} |
506 |
- } |
|
507 |
- f->size=size; |
|
508 |
- FRAG_END(f)->size=f->size; |
|
509 |
-#endif /* QM_JOIN_FREE*/ |
|
509 |
+ f->size=size; |
|
510 |
+ FRAG_END(f)->size=f->size; |
|
511 |
+ } /* if cfg_core->mem_join */ |
|
512 |
+#endif /* MEM_JOIN_FREE*/ |
|
510 | 513 |
#ifdef DBG_QM_MALLOC |
511 | 514 |
f->file=file; |
512 | 515 |
f->func=func; |
... | ... |
@@ -303,10 +303,10 @@ |
303 | 303 |
#define HAVE_RESOLV_RES_STR "" |
304 | 304 |
#endif |
305 | 305 |
|
306 |
-#ifdef QM_JOIN_FREE |
|
307 |
-#define QM_JOIN_FREE_STR ", QM_JOIN_FREE" |
|
306 |
+#ifdef MEM_JOIN_FREE |
|
307 |
+#define MEM_JOIN_FREE_STR ", MEM_JOIN_FREE" |
|
308 | 308 |
#else |
309 |
-#define QM_JOIN_FREE_STR "" |
|
309 |
+#define MEM_JOIN_FREE_STR "" |
|
310 | 310 |
#endif |
311 | 311 |
|
312 | 312 |
#ifdef SYSLOG_CALLBACK_SUPPORT |