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 plus additions
11 that are listed in the file LICENSE.
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 John Walker.
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;
165 return ((struct abufhead *)cp)->ablen;
168 /* Realloc pool memory buffer */
169 POOLMEM *sm_realloc_pool_memory(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
171 char *cp = (char *)obuf;
178 buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE);
181 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
183 ((struct abufhead *)buf)->ablen = size;
184 pool = ((struct abufhead *)buf)->pool;
185 if (size > pool_ctl[pool].max_allocated) {
186 pool_ctl[pool].max_allocated = size;
189 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
192 POOLMEM *sm_check_pool_memory_size(const char *fname, int lineno, POOLMEM *obuf, int32_t size)
195 if (size <= sizeof_pool_memory(obuf)) {
198 return realloc_pool_memory(obuf, size);
201 /* Free a memory buffer */
202 void sm_free_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
204 struct abufhead *buf;
209 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
211 pool_ctl[pool].in_use--;
213 free((char *)buf); /* free nonpooled memory */
214 } else { /* otherwise link it to the free pool chain */
216 struct abufhead *next;
217 /* Don't let him free the same buffer twice */
218 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
220 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
221 Dmsg4(1800, "bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
222 V(mutex); /* unblock the pool */
223 ASSERT(next != buf); /* attempt to free twice */
227 buf->next = pool_ctl[pool].free_buf;
228 pool_ctl[pool].free_buf = buf;
230 Dmsg4(1800, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
237 /* ========= NO SMARTALLOC ========================================= */
239 POOLMEM *get_pool_memory(int pool)
241 struct abufhead *buf;
244 if (pool_ctl[pool].free_buf) {
245 buf = pool_ctl[pool].free_buf;
246 pool_ctl[pool].free_buf = buf->next;
248 return (POOLMEM *)((char *)buf+HEAD_SIZE);
251 if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
253 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
255 buf->ablen = pool_ctl[pool].size;
258 pool_ctl[pool].in_use++;
259 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
260 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
263 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
266 /* Get nonpool memory of size requested */
267 POOLMEM *get_memory(int32_t size)
269 struct abufhead *buf;
272 if ((buf=malloc(size+HEAD_SIZE)) == NULL) {
273 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
278 pool_ctl[pool].in_use++;
279 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
280 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
282 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
286 /* Return the size of a memory buffer */
287 int32_t sizeof_pool_memory(POOLMEM *obuf)
289 char *cp = (char *)obuf;
293 return ((struct abufhead *)cp)->ablen;
298 /* Realloc pool memory buffer */
299 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
301 char *cp = (char *)obuf;
308 buf = realloc(cp, size+HEAD_SIZE);
311 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
313 ((struct abufhead *)buf)->ablen = size;
314 pool = ((struct abufhead *)buf)->pool;
315 if (size > pool_ctl[pool].max_allocated) {
316 pool_ctl[pool].max_allocated = size;
319 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
323 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
326 if (size <= sizeof_pool_memory(obuf)) {
329 return realloc_pool_memory(obuf, size);
332 /* Free a memory buffer */
333 void free_pool_memory(POOLMEM *obuf)
335 struct abufhead *buf;
340 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
342 pool_ctl[pool].in_use--;
344 free((char *)buf); /* free nonpooled memory */
345 } else { /* otherwise link it to the free pool chain */
347 struct abufhead *next;
348 /* Don't let him free the same buffer twice */
349 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
352 ASSERT(next != buf); /* attempt to free twice */
356 buf->next = pool_ctl[pool].free_buf;
357 pool_ctl[pool].free_buf = buf;
359 Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool);
363 #endif /* SMARTALLOC */
367 * Clean up memory pool periodically
370 static time_t last_garbage_collection = 0;
371 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
373 void garbage_collect_memory_pool()
377 Dmsg0(200, "garbage collect memory pool\n");
379 if (last_garbage_collection == 0) {
380 last_garbage_collection = time(NULL);
385 if (now >= last_garbage_collection + garbage_interval) {
386 last_garbage_collection = now;
397 /* Release all pooled memory */
398 void close_memory_pool()
400 struct abufhead *buf, *next;
405 sm_check(__FILE__, __LINE__, false);
407 for (int i=1; i<=PM_MAX; i++) {
408 buf = pool_ctl[i].free_buf;
412 bytes += sizeof_pool_memory((char *)buf);
416 pool_ctl[i].free_buf = NULL;
418 Dmsg2(100, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
425 static const char *pool_name(int pool)
427 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG "};
430 if (pool >= 0 && pool <= PM_MAX) {
433 sprintf(buf, "%-6d", pool);
437 /* Print staticstics on memory pool usage
439 void print_memory_pool_stats()
441 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
442 for (int i=0; i<=PM_MAX; i++)
443 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
444 pool_ctl[i].max_used, pool_ctl[i].in_use);
450 void print_memory_pool_stats() {}
455 * Concatenate a string (str) onto a pool memory buffer pm
456 * Returns: length of concatenated string
458 int pm_strcat(POOLMEM **pm, const char *str)
460 int pmlen = strlen(*pm);
461 int len = strlen(str) + 1;
463 *pm = check_pool_memory_size(*pm, pmlen + len);
464 memcpy(*pm+pmlen, str, len);
465 return pmlen + len - 1;
468 int pm_strcat(POOLMEM *&pm, const char *str)
470 int pmlen = strlen(pm);
471 int len = strlen(str) + 1;
473 pm = check_pool_memory_size(pm, pmlen + len);
474 memcpy(pm+pmlen, str, len);
475 return pmlen + len - 1;
479 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
481 int pmlen = strlen(pm);
482 int len = strlen(str.c_str()) + 1;
484 pm = check_pool_memory_size(pm, pmlen + len);
485 memcpy(pm+pmlen, str.c_str(), len);
486 return pmlen + len - 1;
489 int pm_strcat(POOL_MEM &pm, const char *str)
491 int pmlen = strlen(pm.c_str());
492 int len = strlen(str) + 1;
494 pm.check_size(pmlen + len);
495 memcpy(pm.c_str()+pmlen, str, len);
496 return pmlen + len - 1;
501 * Copy a string (str) into a pool memory buffer pm
502 * Returns: length of string copied
504 int pm_strcpy(POOLMEM **pm, const char *str)
506 int 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)
515 int len = strlen(str) + 1;
517 pm = check_pool_memory_size(pm, len);
518 memcpy(pm, str, len);
522 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
524 int len = strlen(str.c_str()) + 1;
526 pm = check_pool_memory_size(pm, len);
527 memcpy(pm, str.c_str(), len);
532 int pm_strcpy(POOL_MEM &pm, const char *str)
534 int len = strlen(str) + 1;
536 memcpy(pm.c_str(), str, len);
540 /* ============== CLASS POOL_MEM ============== */
542 /* Return the size of a memory buffer */
543 int32_t POOL_MEM::max_size()
548 size = ((struct abufhead *)cp)->ablen;
549 Dmsg1(900, "max_size=%d\n", size);
553 void POOL_MEM::realloc_pm(int32_t size)
561 buf = (char *)realloc(cp, size+HEAD_SIZE);
564 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
566 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
567 ((struct abufhead *)buf)->ablen = size;
568 pool = ((struct abufhead *)buf)->pool;
569 if (size > pool_ctl[pool].max_allocated) {
570 pool_ctl[pool].max_allocated = size;
574 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
577 int POOL_MEM::strcat(const char *str)
579 int pmlen = strlen(mem);
580 int len = strlen(str) + 1;
582 check_size(pmlen + len);
583 memcpy(mem+pmlen, str, len);
584 return pmlen + len - 1;
588 int POOL_MEM::strcpy(const char *str)
590 int len = strlen(str) + 1;
592 memcpy(mem, str, len);