2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Bacula memory pool routines.
31 * The idea behind these routines is that there will be
32 * pools of memory that are pre-allocated for quick
33 * access. The pools will have a fixed memory size on allocation
34 * but if need be, the size can be increased. This is
35 * particularly useful for filename
36 * buffers where 256 bytes should be sufficient in 99.99%
37 * of the cases, but when it isn't we want to be able to
40 * A major advantage of the pool memory aside from the speed
41 * is that the buffer carrys around its size, so to ensure that
42 * there is enough memory, simply call the check_pool_memory_size()
43 * with the desired size and it will adjust only if necessary.
53 int32_t size; /* default size */
54 int32_t max_allocated; /* max allocated */
55 int32_t max_used; /* max buffers used */
56 int32_t in_use; /* number in use */
57 struct abufhead *free_buf; /* pointer to free buffers */
60 /* Bacula Name length plus extra */
61 #define NLEN (MAX_NAME_LENGTH+2)
63 /* #define STRESS_TEST_POOL */
64 #ifndef STRESS_TEST_POOL
66 * Define default Pool buffer sizes
68 static struct s_pool_ctl pool_ctl[] = {
69 { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */
70 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
71 { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */
72 { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */
73 { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */
77 /* This is used ONLY when stress testing the code */
78 static struct s_pool_ctl pool_ctl[] = {
79 { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */
80 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
81 { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */
82 { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */
83 { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */
88 /* Memory allocation control structures and storage. */
90 int32_t ablen; /* Buffer length in bytes */
91 int32_t pool; /* pool */
92 struct abufhead *next; /* pointer to next free buffer */
93 int32_t bnet_size; /* dummy for bnet_send() */
96 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
101 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
103 POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool)
105 struct abufhead *buf;
108 Emsg2(M_ABORT, 0, _("MemPool index %d larger than max %d\n"), pool, PM_MAX);
111 if (pool_ctl[pool].free_buf) {
112 buf = pool_ctl[pool].free_buf;
113 pool_ctl[pool].free_buf = buf->next;
114 pool_ctl[pool].in_use++;
115 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
116 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
119 Dmsg3(1800, "sm_get_pool_memory reuse %p to %s:%d\n", buf, fname, lineno);
120 sm_new_owner(fname, lineno, (char *)buf);
121 return (POOLMEM *)((char *)buf+HEAD_SIZE);
124 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
126 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
128 buf->ablen = pool_ctl[pool].size;
130 pool_ctl[pool].in_use++;
131 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
132 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
135 Dmsg3(1800, "sm_get_pool_memory give %p to %s:%d\n", buf, fname, lineno);
136 return (POOLMEM *)((char *)buf+HEAD_SIZE);
139 /* Get nonpool memory of size requested */
140 POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size)
142 struct abufhead *buf;
145 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) {
146 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
151 pool_ctl[pool].in_use++;
152 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used)
153 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
154 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
158 /* Return the size of a memory buffer */
159 int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
161 char *cp = (char *)obuf;
164 Emsg0(M_ABORT, 0, _("obuf is NULL\n"));
167 return ((struct abufhead *)cp)->ablen;
170 /* Realloc pool memory buffer */
171 POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
173 char *cp = (char *)obuf;
180 buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE);
183 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
185 ((struct abufhead *)buf)->ablen = size;
186 pool = ((struct abufhead *)buf)->pool;
187 if (size > pool_ctl[pool].max_allocated) {
188 pool_ctl[pool].max_allocated = size;
191 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
194 POOLMEM *sm_check_pool_memory_size(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
197 if (size <= sizeof_pool_memory(obuf)) {
200 return realloc_pool_memory(obuf, size);
203 /* Free a memory buffer */
204 void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
206 struct abufhead *buf;
211 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
213 pool_ctl[pool].in_use--;
215 free((char *)buf); /* free nonpooled memory */
216 } else { /* otherwise link it to the free pool chain */
218 struct abufhead *next;
219 /* Don't let him free the same buffer twice */
220 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
222 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
223 Dmsg4(1800, "bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
224 V(mutex); /* unblock the pool */
225 ASSERT(next != buf); /* attempt to free twice */
229 buf->next = pool_ctl[pool].free_buf;
230 pool_ctl[pool].free_buf = buf;
232 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
239 /* ========= NO SMARTALLOC ========================================= */
241 POOLMEM *get_pool_memory(int pool)
243 struct abufhead *buf;
246 if (pool_ctl[pool].free_buf) {
247 buf = pool_ctl[pool].free_buf;
248 pool_ctl[pool].free_buf = buf->next;
250 return (POOLMEM *)((char *)buf+HEAD_SIZE);
253 if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
255 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
257 buf->ablen = pool_ctl[pool].size;
260 pool_ctl[pool].in_use++;
261 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
262 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
265 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
268 /* Get nonpool memory of size requested */
269 POOLMEM *get_memory(int32_t size)
271 struct abufhead *buf;
274 if ((buf=malloc(size+HEAD_SIZE)) == NULL) {
275 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
280 pool_ctl[pool].in_use++;
281 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
282 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
284 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
288 /* Return the size of a memory buffer */
289 int32_t sizeof_pool_memory(POOLMEM *obuf)
291 char *cp = (char *)obuf;
295 return ((struct abufhead *)cp)->ablen;
300 /* Realloc pool memory buffer */
301 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
303 char *cp = (char *)obuf;
310 buf = realloc(cp, size+HEAD_SIZE);
313 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
315 ((struct abufhead *)buf)->ablen = size;
316 pool = ((struct abufhead *)buf)->pool;
317 if (size > pool_ctl[pool].max_allocated) {
318 pool_ctl[pool].max_allocated = size;
321 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
325 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
328 if (size <= sizeof_pool_memory(obuf)) {
331 return realloc_pool_memory(obuf, size);
334 /* Free a memory buffer */
335 void free_pool_memory(POOLMEM *obuf)
337 struct abufhead *buf;
342 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
344 pool_ctl[pool].in_use--;
346 free((char *)buf); /* free nonpooled memory */
347 } else { /* otherwise link it to the free pool chain */
349 struct abufhead *next;
350 /* Don't let him free the same buffer twice */
351 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
354 ASSERT(next != buf); /* attempt to free twice */
358 buf->next = pool_ctl[pool].free_buf;
359 pool_ctl[pool].free_buf = buf;
361 Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool);
365 #endif /* SMARTALLOC */
369 * Clean up memory pool periodically
372 static time_t last_garbage_collection = 0;
373 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
375 void garbage_collect_memory_pool()
379 Dmsg0(200, "garbage collect memory pool\n");
381 if (last_garbage_collection == 0) {
382 last_garbage_collection = time(NULL);
387 if (now >= last_garbage_collection + garbage_interval) {
388 last_garbage_collection = now;
399 /* Release all pooled memory */
400 void close_memory_pool()
402 struct abufhead *buf, *next;
407 sm_check(__FILE__, __LINE__, false);
409 for (int i=1; i<=PM_MAX; i++) {
410 buf = pool_ctl[i].free_buf;
414 bytes += sizeof_pool_memory((char *)buf);
418 pool_ctl[i].free_buf = NULL;
420 Dmsg2(100, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
427 static const char *pool_name(int pool)
429 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG "};
432 if (pool >= 0 && pool <= PM_MAX) {
435 sprintf(buf, "%-6d", pool);
439 /* Print staticstics on memory pool usage
441 void print_memory_pool_stats()
443 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
444 for (int i=0; i<=PM_MAX; i++)
445 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
446 pool_ctl[i].max_used, pool_ctl[i].in_use);
452 void print_memory_pool_stats() {}
457 * Concatenate a string (str) onto a pool memory buffer pm
458 * Returns: length of concatenated string
460 int pm_strcat(POOLMEM **pm, const char *str)
462 int pmlen = strlen(*pm);
467 len = strlen(str) + 1;
468 *pm = check_pool_memory_size(*pm, pmlen + len);
469 memcpy(*pm+pmlen, str, len);
470 return pmlen + len - 1;
473 int pm_strcat(POOLMEM *&pm, const char *str)
475 int pmlen = strlen(pm);
480 len = strlen(str) + 1;
481 pm = check_pool_memory_size(pm, pmlen + len);
482 memcpy(pm+pmlen, str, len);
483 return pmlen + len - 1;
487 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
489 int pmlen = strlen(pm);
490 int len = strlen(str.c_str()) + 1;
492 pm = check_pool_memory_size(pm, pmlen + len);
493 memcpy(pm+pmlen, str.c_str(), len);
494 return pmlen + len - 1;
497 int pm_strcat(POOL_MEM &pm, const char *str)
499 int pmlen = strlen(pm.c_str());
504 len = strlen(str) + 1;
505 pm.check_size(pmlen + len);
506 memcpy(pm.c_str()+pmlen, str, len);
507 return pmlen + len - 1;
512 * Copy a string (str) into a pool memory buffer pm
513 * Returns: length of string copied
515 int pm_strcpy(POOLMEM **pm, const char *str)
521 len = strlen(str) + 1;
522 *pm = check_pool_memory_size(*pm, len);
523 memcpy(*pm, str, len);
527 int pm_strcpy(POOLMEM *&pm, const char *str)
533 len = strlen(str) + 1;
534 pm = check_pool_memory_size(pm, len);
535 memcpy(pm, str, len);
539 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
541 int len = strlen(str.c_str()) + 1;
543 pm = check_pool_memory_size(pm, len);
544 memcpy(pm, str.c_str(), len);
549 int pm_strcpy(POOL_MEM &pm, const char *str)
555 len = strlen(str) + 1;
557 memcpy(pm.c_str(), str, len);
561 /* ============== CLASS POOL_MEM ============== */
563 /* Return the size of a memory buffer */
564 int32_t POOL_MEM::max_size()
569 size = ((struct abufhead *)cp)->ablen;
570 Dmsg1(900, "max_size=%d\n", size);
574 void POOL_MEM::realloc_pm(int32_t size)
582 buf = (char *)realloc(cp, size+HEAD_SIZE);
585 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
587 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
588 ((struct abufhead *)buf)->ablen = size;
589 pool = ((struct abufhead *)buf)->pool;
590 if (size > pool_ctl[pool].max_allocated) {
591 pool_ctl[pool].max_allocated = size;
595 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
598 int POOL_MEM::strcat(const char *str)
600 int pmlen = strlen(mem);
605 len = strlen(str) + 1;
606 check_size(pmlen + len);
607 memcpy(mem+pmlen, str, len);
608 return pmlen + len - 1;
612 int POOL_MEM::strcpy(const char *str)
618 len = strlen(str) + 1;
620 memcpy(mem, str, len);