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;
100 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
102 POOLMEM *sm_get_pool_memory(const char *fname, int lineno, int pool)
104 struct abufhead *buf;
107 Emsg2(M_ABORT, 0, _("MemPool index %d larger than max %d\n"), pool, PM_MAX);
110 if (pool_ctl[pool].free_buf) {
111 buf = pool_ctl[pool].free_buf;
112 pool_ctl[pool].free_buf = buf->next;
113 pool_ctl[pool].in_use++;
114 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
115 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
118 Dmsg3(1800, "sm_get_pool_memory reuse %p to %s:%d\n", buf, fname, lineno);
119 sm_new_owner(fname, lineno, (char *)buf);
120 return (POOLMEM *)((char *)buf+HEAD_SIZE);
123 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
125 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
127 buf->ablen = pool_ctl[pool].size;
129 pool_ctl[pool].in_use++;
130 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
131 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
134 Dmsg3(1800, "sm_get_pool_memory give %p to %s:%d\n", buf, fname, lineno);
135 return (POOLMEM *)((char *)buf+HEAD_SIZE);
138 /* Get nonpool memory of size requested */
139 POOLMEM *sm_get_memory(const char *fname, int lineno, int32_t size)
141 struct abufhead *buf;
144 if ((buf = (struct abufhead *)sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) {
145 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
150 pool_ctl[pool].in_use++;
151 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used)
152 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
153 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
156 /* Return the size of a memory buffer */
157 int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
159 char *cp = (char *)obuf;
162 Emsg0(M_ABORT, 0, _("obuf is NULL\n"));
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);
236 /* ========= NO SMARTALLOC ========================================= */
238 POOLMEM *get_pool_memory(int pool)
240 struct abufhead *buf;
243 if (pool_ctl[pool].free_buf) {
244 buf = pool_ctl[pool].free_buf;
245 pool_ctl[pool].free_buf = buf->next;
247 return (POOLMEM *)((char *)buf+HEAD_SIZE);
250 if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) {
252 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), pool_ctl[pool].size);
254 buf->ablen = pool_ctl[pool].size;
257 pool_ctl[pool].in_use++;
258 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
259 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
262 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
265 /* Get nonpool memory of size requested */
266 POOLMEM *get_memory(int32_t size)
268 struct abufhead *buf;
271 if ((buf=malloc(size+HEAD_SIZE)) == NULL) {
272 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
277 pool_ctl[pool].in_use++;
278 if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) {
279 pool_ctl[pool].max_used = pool_ctl[pool].in_use;
281 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
284 /* Return the size of a memory buffer */
285 int32_t sizeof_pool_memory(POOLMEM *obuf)
287 char *cp = (char *)obuf;
291 return ((struct abufhead *)cp)->ablen;
294 /* Realloc pool memory buffer */
295 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
297 char *cp = (char *)obuf;
304 buf = realloc(cp, size+HEAD_SIZE);
307 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
309 ((struct abufhead *)buf)->ablen = size;
310 pool = ((struct abufhead *)buf)->pool;
311 if (size > pool_ctl[pool].max_allocated) {
312 pool_ctl[pool].max_allocated = size;
315 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
318 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
321 if (size <= sizeof_pool_memory(obuf)) {
324 return realloc_pool_memory(obuf, size);
327 /* Free a memory buffer */
328 void free_pool_memory(POOLMEM *obuf)
330 struct abufhead *buf;
335 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
337 pool_ctl[pool].in_use--;
339 free((char *)buf); /* free nonpooled memory */
340 } else { /* otherwise link it to the free pool chain */
342 struct abufhead *next;
343 /* Don't let him free the same buffer twice */
344 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
347 ASSERT(next != buf); /* attempt to free twice */
351 buf->next = pool_ctl[pool].free_buf;
352 pool_ctl[pool].free_buf = buf;
354 Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool);
357 #endif /* SMARTALLOC */
360 * Clean up memory pool periodically
363 static time_t last_garbage_collection = 0;
364 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
366 void garbage_collect_memory_pool()
370 Dmsg0(200, "garbage collect memory pool\n");
372 if (last_garbage_collection == 0) {
373 last_garbage_collection = time(NULL);
378 if (now >= last_garbage_collection + garbage_interval) {
379 last_garbage_collection = now;
387 /* Release all pooled memory */
388 void close_memory_pool()
390 struct abufhead *buf, *next;
395 sm_check(__FILE__, __LINE__, false);
397 for (int i=1; i<=PM_MAX; i++) {
398 buf = pool_ctl[i].free_buf;
402 bytes += sizeof_pool_memory((char *)buf);
406 pool_ctl[i].free_buf = NULL;
408 Dmsg2(100, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
414 static const char *pool_name(int pool)
416 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG "};
419 if (pool >= 0 && pool <= PM_MAX) {
422 sprintf(buf, "%-6d", pool);
426 /* Print staticstics on memory pool usage
428 void print_memory_pool_stats()
430 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
431 for (int i=0; i<=PM_MAX; i++)
432 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
433 pool_ctl[i].max_used, pool_ctl[i].in_use);
439 void print_memory_pool_stats() {}
443 * Concatenate a string (str) onto a pool memory buffer pm
444 * Returns: length of concatenated string
446 int pm_strcat(POOLMEM **pm, const char *str)
448 int pmlen = strlen(*pm);
453 len = strlen(str) + 1;
454 *pm = check_pool_memory_size(*pm, pmlen + len);
455 memcpy(*pm+pmlen, str, len);
456 return pmlen + len - 1;
459 int pm_strcat(POOLMEM *&pm, const char *str)
461 int pmlen = strlen(pm);
466 len = strlen(str) + 1;
467 pm = check_pool_memory_size(pm, pmlen + len);
468 memcpy(pm+pmlen, str, len);
469 return pmlen + len - 1;
472 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
474 int pmlen = strlen(pm);
475 int len = strlen(str.c_str()) + 1;
477 pm = check_pool_memory_size(pm, pmlen + len);
478 memcpy(pm+pmlen, str.c_str(), len);
479 return pmlen + len - 1;
482 int pm_strcat(POOL_MEM &pm, const char *str)
484 int pmlen = strlen(pm.c_str());
489 len = strlen(str) + 1;
490 pm.check_size(pmlen + len);
491 memcpy(pm.c_str()+pmlen, str, len);
492 return pmlen + len - 1;
496 * Copy a string (str) into a pool memory buffer pm
497 * Returns: length of string copied
499 int pm_strcpy(POOLMEM **pm, const char *str)
505 len = strlen(str) + 1;
506 *pm = check_pool_memory_size(*pm, len);
507 memcpy(*pm, str, len);
511 int pm_strcpy(POOLMEM *&pm, const char *str)
517 len = strlen(str) + 1;
518 pm = check_pool_memory_size(pm, len);
519 memcpy(pm, str, len);
523 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
525 int len = strlen(str.c_str()) + 1;
527 pm = check_pool_memory_size(pm, len);
528 memcpy(pm, str.c_str(), len);
532 int pm_strcpy(POOL_MEM &pm, const char *str)
538 len = strlen(str) + 1;
540 memcpy(pm.c_str(), str, len);
545 * Copy data into a pool memory buffer pm
546 * Returns: length of data copied
548 int pm_memcpy(POOLMEM **pm, const void *data, size_t n)
550 *pm = check_pool_memory_size(*pm, n);
551 memcpy(*pm, data, n);
555 int pm_memcpy(POOLMEM *&pm, const void *data, size_t n)
557 pm = check_pool_memory_size(pm, n);
562 int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, size_t n)
564 pm = check_pool_memory_size(pm, n);
565 memcpy(pm, data.c_str(), n);
569 int pm_memcpy(POOL_MEM &pm, const void *data, size_t n)
572 memcpy(pm.c_str(), data, n);
576 /* ============== CLASS POOL_MEM ============== */
578 /* Return the size of a memory buffer */
579 int32_t POOL_MEM::max_size()
584 size = ((struct abufhead *)cp)->ablen;
585 Dmsg1(900, "max_size=%d\n", size);
589 void POOL_MEM::realloc_pm(int32_t size)
597 buf = (char *)realloc(cp, size+HEAD_SIZE);
600 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
602 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
603 ((struct abufhead *)buf)->ablen = size;
604 pool = ((struct abufhead *)buf)->pool;
605 if (size > pool_ctl[pool].max_allocated) {
606 pool_ctl[pool].max_allocated = size;
610 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
613 int POOL_MEM::strcat(const char *str)
615 int pmlen = strlen(mem);
620 len = strlen(str) + 1;
621 check_size(pmlen + len);
622 memcpy(mem+pmlen, str, len);
623 return pmlen + len - 1;
626 int POOL_MEM::strcpy(const char *str)
632 len = strlen(str) + 1;
634 memcpy(mem, str, len);