X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fmem_pool.c;h=61dc1bf52d3404c1e1c06ac4fe6590b81204f702;hb=3f8a3a045ea058657030f588a10f786449d00e0d;hp=0a2624243c2afc1c804cd7b87cf39426f1b1a80d;hpb=ea40e01f28ccef06e405a7ebc7295392b5745532;p=bacula%2Fbacula diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 0a2624243c..61dc1bf52d 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -1,10 +1,10 @@ /* - * Bacula memory pool routines. + * Bacula memory pool routines. * * The idea behind these routines is that there will be * pools of memory that are pre-allocated for quick * access. The pools will have a fixed memory size on allocation - * but if need be, the size can be increased. This is + * but if need be, the size can be increased. This is * particularly useful for filename * buffers where 256 bytes should be sufficient in 99.99% * of the cases, but when it isn't we want to be able to @@ -21,22 +21,17 @@ */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -97,7 +92,7 @@ POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool) struct abufhead *buf; if (pool > PM_MAX) { - Emsg2(M_ABORT, 0, "MemPool index %d larger than max %d\n", pool, PM_MAX); + Emsg2(M_ABORT, 0, _("MemPool index %d larger than max %d\n"), pool, PM_MAX); } P(mutex); if (pool_ctl[pool].free_buf) { @@ -108,14 +103,14 @@ POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool) pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); - Dmsg3(300, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno); + Dmsg3(1800, "sm_get_pool_memory reuse %p to %s:%d\n", buf, fname, lineno); sm_new_owner(fname, lineno, (char *)buf); return (POOLMEM *)((char *)buf+HEAD_SIZE); } - + if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) { V(mutex); - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", pool_ctl[pool].size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size); } buf->ablen = pool_ctl[pool].size; buf->pool = pool; @@ -124,7 +119,7 @@ POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool) pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); - Dmsg3(300, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno); + Dmsg3(1800, "sm_get_pool_memory give %p to %s:%d\n", buf, fname, lineno); return (POOLMEM *)((char *)buf+HEAD_SIZE); } @@ -135,7 +130,7 @@ POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size) int pool = 0; if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) { - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } buf->ablen = size; buf->pool = pool; @@ -170,7 +165,7 @@ POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, in buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE); if (buf == NULL) { V(mutex); - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; @@ -209,7 +204,8 @@ void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf) /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { if (next == buf) { - Dmsg4(300, "bad free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno); + Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno); + Dmsg4(1800, "bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno); V(mutex); /* unblock the pool */ ASSERT(next != buf); /* attempt to free twice */ } @@ -218,7 +214,7 @@ void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf) buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } - Dmsg4(300, "free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno); + Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno); V(mutex); } @@ -238,10 +234,10 @@ POOLMEM *get_pool_memory(int pool) V(mutex); return (POOLMEM *)((char *)buf+HEAD_SIZE); } - + if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) { V(mutex); - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", pool_ctl[pool].size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size); } buf->ablen = pool_ctl[pool].size; buf->pool = pool; @@ -261,7 +257,7 @@ POOLMEM *get_memory(int32_t size) int pool = 0; if ((buf=malloc(size+HEAD_SIZE)) == NULL) { - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } buf->ablen = size; buf->pool = pool; @@ -299,7 +295,7 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size) buf = realloc(cp, size+HEAD_SIZE); if (buf == NULL) { V(mutex); - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; @@ -347,13 +343,40 @@ void free_pool_memory(POOLMEM *obuf) buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } - Dmsg2(300, "free_pool_memory %x pool=%d\n", buf, pool); + Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool); V(mutex); } #endif /* SMARTALLOC */ +/* + * Clean up memory pool periodically + * + */ +static time_t last_garbage_collection = 0; +const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */ + +void garbage_collect_memory_pool() +{ + time_t now; + + Dmsg0(200, "garbage collect memory pool\n"); + P(mutex); + if (last_garbage_collection == 0) { + last_garbage_collection = time(NULL); + V(mutex); + return; + } + now = time(NULL); + if (now >= last_garbage_collection + garbage_interval) { + last_garbage_collection = now; + V(mutex); + close_memory_pool(); + } else { + V(mutex); + } +} @@ -362,6 +385,9 @@ void free_pool_memory(POOLMEM *obuf) void close_memory_pool() { struct abufhead *buf, *next; + int count = 0; + uint64_t bytes = 0; + char ed1[50]; sm_check(__FILE__, __LINE__, false); P(mutex); @@ -369,12 +395,16 @@ void close_memory_pool() buf = pool_ctl[i].free_buf; while (buf) { next = buf->next; + count++; + bytes += sizeof_pool_memory((char *)buf); free((char *)buf); buf = next; } pool_ctl[i].free_buf = NULL; } + Dmsg2(100, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1)); V(mutex); + } #ifdef DEBUG @@ -390,21 +420,21 @@ static const char *pool_name(int pool) sprintf(buf, "%-6d", pool); return buf; } - -/* Print staticstics on memory pool usage - */ + +/* Print staticstics on memory pool usage + */ void print_memory_pool_stats() { - Dmsg0(-1, "Pool Maxsize Maxused Inuse\n"); + Pmsg0(-1, "Pool Maxsize Maxused Inuse\n"); for (int i=0; i<=PM_MAX; i++) - Dmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated, + Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated, pool_ctl[i].max_used, pool_ctl[i].in_use); - Dmsg0(-1, "\n"); + Pmsg0(-1, "\n"); } #else -void print_memory_pool_stats() {} +void print_memory_pool_stats() {} #endif /* DEBUG */ @@ -487,7 +517,7 @@ int pm_strcpy(POOLMEM *&pm, POOL_MEM &str) int pm_strcpy(POOL_MEM &pm, const char *str) -{ +{ int len = strlen(str) + 1; pm.check_size(len); memcpy(pm.c_str(), str, len); @@ -503,7 +533,7 @@ int32_t POOL_MEM::max_size() char *cp = mem; cp -= HEAD_SIZE; size = ((struct abufhead *)cp)->ablen; - Dmsg1(000, "max_size=%d\n", size); + Dmsg1(900, "max_size=%d\n", size); return size; } @@ -518,9 +548,9 @@ void POOL_MEM::realloc_pm(int32_t size) buf = (char *)realloc(cp, size+HEAD_SIZE); if (buf == NULL) { V(mutex); - Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size); } - Dmsg2(000, "Old buf=0x%x new buf=0x%x\n", cp, buf); + Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf); ((struct abufhead *)buf)->ablen = size; pool = ((struct abufhead *)buf)->pool; if (size > pool_ctl[pool].max_allocated) { @@ -528,7 +558,7 @@ void POOL_MEM::realloc_pm(int32_t size) } mem = buf+HEAD_SIZE; V(mutex); - Dmsg3(000, "Old buf=0x%x new buf=0x%x mem=0x%x\n", cp, buf, mem); + Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem); } int POOL_MEM::strcat(const char *str) @@ -543,7 +573,7 @@ int POOL_MEM::strcat(const char *str) int POOL_MEM::strcpy(const char *str) -{ +{ int len = strlen(str) + 1; check_size(len); memcpy(mem, str, len);