2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 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 three of the GNU Affero 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 Affero 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.
52 int32_t size; /* default size */
53 int32_t max_allocated; /* max allocated */
54 int32_t max_used; /* max buffers used */
55 int32_t in_use; /* number in use */
56 struct abufhead *free_buf; /* pointer to free buffers */
59 /* Bacula Name length plus extra */
60 #define NLEN (MAX_NAME_LENGTH+2)
62 /* #define STRESS_TEST_POOL */
63 #ifndef STRESS_TEST_POOL
65 * Define default Pool buffer sizes
67 static struct s_pool_ctl pool_ctl[] = {
68 { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */
69 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
70 { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */
71 { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */
72 { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */
76 /* This is used ONLY when stress testing the code */
77 static struct s_pool_ctl pool_ctl[] = {
78 { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */
79 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
80 { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */
81 { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */
82 { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */
87 /* Memory allocation control structures and storage. */
89 int32_t ablen; /* Buffer length in bytes */
90 int32_t pool; /* pool */
91 struct abufhead *next; /* pointer to next free buffer */
92 int32_t bnet_size; /* dummy for bnet_send() */
95 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
99 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
101 POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool)
103 struct abufhead *buf;
106 Emsg2(M_ABORT, 0, _("MemPool index %d larger than max %d\n"), pool, PM_MAX);
109 if (pool_ctl[pool].free_buf) {
110 buf = pool_ctl[pool].free_buf;
111 pool_ctl[pool].free_buf = buf->next;
112 pool_ctl[pool].in_use++;
113 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
114 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
117 Dmsg3(1800, "sm_get_pool_memory reuse %p to %s:%d\n", buf, fname, lineno);
118 sm_new_owner(fname, lineno, (char *)buf);
119 return (POOLMEM *)((char *)buf+HEAD_SIZE);
122 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
124 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
126 buf->ablen = pool_ctl[pool].size;
128 pool_ctl[pool].in_use++;
129 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
130 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
133 Dmsg3(1800, "sm_get_pool_memory give %p to %s:%d\n", buf, fname, lineno);
134 return (POOLMEM *)((char *)buf+HEAD_SIZE);
137 /* Get nonpool memory of size requested */
138 POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size)
140 struct abufhead *buf;
143 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) {
144 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
149 pool_ctl[pool].in_use++;
150 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used)
151 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
152 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
155 /* Return the size of a memory buffer */
156 int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
158 char *cp = (char *)obuf;
161 Emsg0(M_ABORT, 0, _("obuf is NULL\n"));
164 return ((struct abufhead *)cp)->ablen;
167 /* Realloc pool memory buffer */
168 POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
170 char *cp = (char *)obuf;
177 buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE);
180 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
182 ((struct abufhead *)buf)->ablen = size;
183 pool = ((struct abufhead *)buf)->pool;
184 if (size > pool_ctl[pool].max_allocated) {
185 pool_ctl[pool].max_allocated = size;
188 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
191 POOLMEM *sm_check_pool_memory_size(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
194 if (size <= sizeof_pool_memory(obuf)) {
197 return realloc_pool_memory(obuf, size);
200 /* Free a memory buffer */
201 void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
203 struct abufhead *buf;
208 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
210 pool_ctl[pool].in_use--;
212 free((char *)buf); /* free nonpooled memory */
213 } else { /* otherwise link it to the free pool chain */
215 struct abufhead *next;
216 /* Don't let him free the same buffer twice */
217 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
219 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
220 Dmsg4(1800, "bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
221 V(mutex); /* unblock the pool */
222 ASSERT(next != buf); /* attempt to free twice */
226 buf->next = pool_ctl[pool].free_buf;
227 pool_ctl[pool].free_buf = buf;
229 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
235 /* ========= NO SMARTALLOC ========================================= */
237 POOLMEM *get_pool_memory(int pool)
239 struct abufhead *buf;
242 if (pool_ctl[pool].free_buf) {
243 buf = pool_ctl[pool].free_buf;
244 pool_ctl[pool].free_buf = buf->next;
246 return (POOLMEM *)((char *)buf+HEAD_SIZE);
249 if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
251 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
253 buf->ablen = pool_ctl[pool].size;
256 pool_ctl[pool].in_use++;
257 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
258 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
261 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
264 /* Get nonpool memory of size requested */
265 POOLMEM *get_memory(int32_t size)
267 struct abufhead *buf;
270 if ((buf=malloc(size+HEAD_SIZE)) == NULL) {
271 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
276 pool_ctl[pool].in_use++;
277 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
278 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
280 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
283 /* Return the size of a memory buffer */
284 int32_t sizeof_pool_memory(POOLMEM *obuf)
286 char *cp = (char *)obuf;
290 return ((struct abufhead *)cp)->ablen;
293 /* Realloc pool memory buffer */
294 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
296 char *cp = (char *)obuf;
303 buf = realloc(cp, size+HEAD_SIZE);
306 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
308 ((struct abufhead *)buf)->ablen = size;
309 pool = ((struct abufhead *)buf)->pool;
310 if (size > pool_ctl[pool].max_allocated) {
311 pool_ctl[pool].max_allocated = size;
314 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
317 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
320 if (size <= sizeof_pool_memory(obuf)) {
323 return realloc_pool_memory(obuf, size);
326 /* Free a memory buffer */
327 void free_pool_memory(POOLMEM *obuf)
329 struct abufhead *buf;
334 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
336 pool_ctl[pool].in_use--;
338 free((char *)buf); /* free nonpooled memory */
339 } else { /* otherwise link it to the free pool chain */
341 struct abufhead *next;
342 /* Don't let him free the same buffer twice */
343 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
346 ASSERT(next != buf); /* attempt to free twice */
350 buf->next = pool_ctl[pool].free_buf;
351 pool_ctl[pool].free_buf = buf;
353 Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool);
356 #endif /* SMARTALLOC */
359 * Clean up memory pool periodically
362 static time_t last_garbage_collection = 0;
363 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
365 void garbage_collect_memory_pool()
369 Dmsg0(200, "garbage collect memory pool\n");
371 if (last_garbage_collection == 0) {
372 last_garbage_collection = time(NULL);
377 if (now >= last_garbage_collection + garbage_interval) {
378 last_garbage_collection = now;
386 /* Release all pooled memory */
387 void close_memory_pool()
389 struct abufhead *buf, *next;
394 sm_check(__FILE__, __LINE__, false);
396 for (int i=1; i<=PM_MAX; i++) {
397 buf = pool_ctl[i].free_buf;
401 bytes += sizeof_pool_memory((char *)buf);
405 pool_ctl[i].free_buf = NULL;
407 Dmsg2(001, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
408 if (debug_level >= 1) {
409 print_memory_pool_stats();
416 static const char *pool_name(int pool)
418 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG "};
421 if (pool >= 0 && pool <= PM_MAX) {
424 sprintf(buf, "%-6d", pool);
428 /* Print staticstics on memory pool usage
430 void print_memory_pool_stats()
432 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
433 for (int i=0; i<=PM_MAX; i++)
434 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
435 pool_ctl[i].max_used, pool_ctl[i].in_use);
441 void print_memory_pool_stats() {}
445 * Concatenate a string (str) onto a pool memory buffer pm
446 * Returns: length of concatenated string
448 int pm_strcat(POOLMEM **pm, const char *str)
450 int pmlen = strlen(*pm);
455 len = strlen(str) + 1;
456 *pm = check_pool_memory_size(*pm, pmlen + len);
457 memcpy(*pm+pmlen, str, len);
458 return pmlen + len - 1;
461 int pm_strcat(POOLMEM *&pm, const char *str)
463 int pmlen = strlen(pm);
468 len = strlen(str) + 1;
469 pm = check_pool_memory_size(pm, pmlen + len);
470 memcpy(pm+pmlen, str, len);
471 return pmlen + len - 1;
474 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
476 int pmlen = strlen(pm);
477 int len = strlen(str.c_str()) + 1;
479 pm = check_pool_memory_size(pm, pmlen + len);
480 memcpy(pm+pmlen, str.c_str(), len);
481 return pmlen + len - 1;
484 int pm_strcat(POOL_MEM &pm, const char *str)
486 int pmlen = strlen(pm.c_str());
491 len = strlen(str) + 1;
492 pm.check_size(pmlen + len);
493 memcpy(pm.c_str()+pmlen, str, len);
494 return pmlen + len - 1;
498 * Copy a string (str) into a pool memory buffer pm
499 * Returns: length of string copied
501 int pm_strcpy(POOLMEM **pm, const char *str)
507 len = strlen(str) + 1;
508 *pm = check_pool_memory_size(*pm, len);
509 memcpy(*pm, str, len);
513 int pm_strcpy(POOLMEM *&pm, const char *str)
519 len = strlen(str) + 1;
520 pm = check_pool_memory_size(pm, len);
521 memcpy(pm, str, len);
525 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
527 int len = strlen(str.c_str()) + 1;
529 pm = check_pool_memory_size(pm, len);
530 memcpy(pm, str.c_str(), len);
534 int pm_strcpy(POOL_MEM &pm, const char *str)
540 len = strlen(str) + 1;
542 memcpy(pm.c_str(), str, len);
547 * Copy data into a pool memory buffer pm
548 * Returns: length of data copied
550 int pm_memcpy(POOLMEM **pm, const char *data, int32_t n)
552 *pm = check_pool_memory_size(*pm, n);
553 memcpy(*pm, data, n);
557 int pm_memcpy(POOLMEM *&pm, const char *data, int32_t n)
559 pm = check_pool_memory_size(pm, n);
564 int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, int32_t n)
566 pm = check_pool_memory_size(pm, n);
567 memcpy(pm, data.c_str(), n);
571 int pm_memcpy(POOL_MEM &pm, const char *data, int32_t n)
574 memcpy(pm.c_str(), data, n);
578 /* ============== CLASS POOL_MEM ============== */
580 /* Return the size of a memory buffer */
581 int32_t POOL_MEM::max_size()
586 size = ((struct abufhead *)cp)->ablen;
587 Dmsg1(900, "max_size=%d\n", size);
591 void POOL_MEM::realloc_pm(int32_t size)
599 buf = (char *)realloc(cp, size+HEAD_SIZE);
602 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
604 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
605 ((struct abufhead *)buf)->ablen = size;
606 pool = ((struct abufhead *)buf)->pool;
607 if (size > pool_ctl[pool].max_allocated) {
608 pool_ctl[pool].max_allocated = size;
612 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
615 int POOL_MEM::strcat(const char *str)
617 int pmlen = strlen(mem);
622 len = strlen(str) + 1;
623 check_size(pmlen + len);
624 memcpy(mem+pmlen, str, len);
625 return pmlen + len - 1;
628 int POOL_MEM::strcpy(const char *str)
634 len = strlen(str) + 1;
636 memcpy(mem, str, len);