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 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);
465 len = strlen(str) + 1;
466 *pm = check_pool_memory_size(*pm, pmlen + len);
467 memcpy(*pm+pmlen, str, len);
468 return pmlen + len - 1;
471 int pm_strcat(POOLMEM *&pm, const char *str)
473 int pmlen = strlen(pm);
478 len = strlen(str) + 1;
479 pm = check_pool_memory_size(pm, pmlen + len);
480 memcpy(pm+pmlen, str, len);
481 return pmlen + len - 1;
485 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
487 int pmlen = strlen(pm);
488 int len = strlen(str.c_str()) + 1;
490 pm = check_pool_memory_size(pm, pmlen + len);
491 memcpy(pm+pmlen, str.c_str(), len);
492 return pmlen + len - 1;
495 int pm_strcat(POOL_MEM &pm, const char *str)
497 int pmlen = strlen(pm.c_str());
502 len = strlen(str) + 1;
503 pm.check_size(pmlen + len);
504 memcpy(pm.c_str()+pmlen, str, len);
505 return pmlen + len - 1;
510 * Copy a string (str) into a pool memory buffer pm
511 * Returns: length of string copied
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, const char *str)
531 len = strlen(str) + 1;
532 pm = check_pool_memory_size(pm, len);
533 memcpy(pm, str, len);
537 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
539 int len = strlen(str.c_str()) + 1;
541 pm = check_pool_memory_size(pm, len);
542 memcpy(pm, str.c_str(), len);
547 int pm_strcpy(POOL_MEM &pm, const char *str)
553 len = strlen(str) + 1;
555 memcpy(pm.c_str(), str, len);
559 /* ============== CLASS POOL_MEM ============== */
561 /* Return the size of a memory buffer */
562 int32_t POOL_MEM::max_size()
567 size = ((struct abufhead *)cp)->ablen;
568 Dmsg1(900, "max_size=%d\n", size);
572 void POOL_MEM::realloc_pm(int32_t size)
580 buf = (char *)realloc(cp, size+HEAD_SIZE);
583 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
585 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
586 ((struct abufhead *)buf)->ablen = size;
587 pool = ((struct abufhead *)buf)->pool;
588 if (size > pool_ctl[pool].max_allocated) {
589 pool_ctl[pool].max_allocated = size;
593 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
596 int POOL_MEM::strcat(const char *str)
598 int pmlen = strlen(mem);
603 len = strlen(str) + 1;
604 check_size(pmlen + len);
605 memcpy(mem+pmlen, str, len);
606 return pmlen + len - 1;
610 int POOL_MEM::strcpy(const char *str)
616 len = strlen(str) + 1;
618 memcpy(mem, str, len);