2 * Bacula memory pool routines.
4 * The idea behind these routines is that there will be
5 * pools of memory that are pre-allocated for quick
6 * access. The pools will have a fixed memory size on allocation
7 * but if need be, the size can be increased. This is
8 * particularly useful for filename
9 * buffers where 256 bytes should be sufficient in 99.99%
10 * of the cases, but when it isn't we want to be able to
13 * A major advantage of the pool memory aside from the speed
14 * is that the buffer carrys around its size, so to ensure that
15 * there is enough memory, simply call the check_pool_memory_size()
16 * with the desired size and it will adjust only if necessary.
23 Bacula® - The Network Backup Solution
25 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
27 The main author of Bacula is Kern Sibbald, with contributions from
28 many others, a complete list can be found in the file AUTHORS.
29 This program is Free Software; you can redistribute it and/or
30 modify it under the terms of version two of the GNU General Public
31 License as published by the Free Software Foundation plus additions
32 that are listed in the file LICENSE.
34 This program is distributed in the hope that it will be useful, but
35 WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 General Public License for more details.
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
44 Bacula® is a registered trademark of John Walker.
45 The licensor of Bacula is the Free Software Foundation Europe
46 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
47 Switzerland, email:ftf@fsfeurope.org.
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 */
95 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);
157 /* Return the size of a memory buffer */
158 int32_t sm_sizeof_pool_memory(const char *fname, int lineno, POOLMEM *obuf)
160 char *cp = (char *)obuf;
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);
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);
285 /* Return the size of a memory buffer */
286 int32_t sizeof_pool_memory(POOLMEM *obuf)
288 char *cp = (char *)obuf;
292 return ((struct abufhead *)cp)->ablen;
297 /* Realloc pool memory buffer */
298 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
300 char *cp = (char *)obuf;
307 buf = realloc(cp, size+HEAD_SIZE);
310 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
312 ((struct abufhead *)buf)->ablen = size;
313 pool = ((struct abufhead *)buf)->pool;
314 if (size > pool_ctl[pool].max_allocated) {
315 pool_ctl[pool].max_allocated = size;
318 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
322 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
325 if (size <= sizeof_pool_memory(obuf)) {
328 return realloc_pool_memory(obuf, size);
331 /* Free a memory buffer */
332 void free_pool_memory(POOLMEM *obuf)
334 struct abufhead *buf;
339 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
341 pool_ctl[pool].in_use--;
343 free((char *)buf); /* free nonpooled memory */
344 } else { /* otherwise link it to the free pool chain */
346 struct abufhead *next;
347 /* Don't let him free the same buffer twice */
348 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
351 ASSERT(next != buf); /* attempt to free twice */
355 buf->next = pool_ctl[pool].free_buf;
356 pool_ctl[pool].free_buf = buf;
358 Dmsg2(1800, "free_pool_memory %p pool=%d\n", buf, pool);
362 #endif /* SMARTALLOC */
366 * Clean up memory pool periodically
369 static time_t last_garbage_collection = 0;
370 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
372 void garbage_collect_memory_pool()
376 Dmsg0(200, "garbage collect memory pool\n");
378 if (last_garbage_collection == 0) {
379 last_garbage_collection = time(NULL);
384 if (now >= last_garbage_collection + garbage_interval) {
385 last_garbage_collection = now;
396 /* Release all pooled memory */
397 void close_memory_pool()
399 struct abufhead *buf, *next;
404 sm_check(__FILE__, __LINE__, false);
406 for (int i=1; i<=PM_MAX; i++) {
407 buf = pool_ctl[i].free_buf;
411 bytes += sizeof_pool_memory((char *)buf);
415 pool_ctl[i].free_buf = NULL;
417 Dmsg2(100, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
424 static const char *pool_name(int pool)
426 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG "};
429 if (pool >= 0 && pool <= PM_MAX) {
432 sprintf(buf, "%-6d", pool);
436 /* Print staticstics on memory pool usage
438 void print_memory_pool_stats()
440 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
441 for (int i=0; i<=PM_MAX; i++)
442 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
443 pool_ctl[i].max_used, pool_ctl[i].in_use);
449 void print_memory_pool_stats() {}
454 * Concatenate a string (str) onto a pool memory buffer pm
455 * Returns: length of concatenated string
457 int pm_strcat(POOLMEM **pm, const char *str)
459 int pmlen = strlen(*pm);
460 int len = strlen(str) + 1;
462 *pm = check_pool_memory_size(*pm, pmlen + len);
463 memcpy(*pm+pmlen, str, len);
464 return pmlen + len - 1;
467 int pm_strcat(POOLMEM *&pm, const char *str)
469 int pmlen = strlen(pm);
470 int len = strlen(str) + 1;
472 pm = check_pool_memory_size(pm, pmlen + len);
473 memcpy(pm+pmlen, str, len);
474 return pmlen + len - 1;
478 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
480 int pmlen = strlen(pm);
481 int len = strlen(str.c_str()) + 1;
483 pm = check_pool_memory_size(pm, pmlen + len);
484 memcpy(pm+pmlen, str.c_str(), len);
485 return pmlen + len - 1;
488 int pm_strcat(POOL_MEM &pm, const char *str)
490 int pmlen = strlen(pm.c_str());
491 int len = strlen(str) + 1;
493 pm.check_size(pmlen + len);
494 memcpy(pm.c_str()+pmlen, str, len);
495 return pmlen + len - 1;
500 * Copy a string (str) into a pool memory buffer pm
501 * Returns: length of string copied
503 int pm_strcpy(POOLMEM **pm, const char *str)
505 int len = strlen(str) + 1;
507 *pm = check_pool_memory_size(*pm, len);
508 memcpy(*pm, str, len);
512 int pm_strcpy(POOLMEM *&pm, const char *str)
514 int len = strlen(str) + 1;
516 pm = check_pool_memory_size(pm, len);
517 memcpy(pm, str, len);
521 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
523 int len = strlen(str.c_str()) + 1;
525 pm = check_pool_memory_size(pm, len);
526 memcpy(pm, str.c_str(), len);
531 int pm_strcpy(POOL_MEM &pm, const char *str)
533 int len = strlen(str) + 1;
535 memcpy(pm.c_str(), str, len);
539 /* ============== CLASS POOL_MEM ============== */
541 /* Return the size of a memory buffer */
542 int32_t POOL_MEM::max_size()
547 size = ((struct abufhead *)cp)->ablen;
548 Dmsg1(900, "max_size=%d\n", size);
552 void POOL_MEM::realloc_pm(int32_t size)
560 buf = (char *)realloc(cp, size+HEAD_SIZE);
563 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
565 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
566 ((struct abufhead *)buf)->ablen = size;
567 pool = ((struct abufhead *)buf)->pool;
568 if (size > pool_ctl[pool].max_allocated) {
569 pool_ctl[pool].max_allocated = size;
573 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
576 int POOL_MEM::strcat(const char *str)
578 int pmlen = strlen(mem);
579 int len = strlen(str) + 1;
581 check_size(pmlen + len);
582 memcpy(mem+pmlen, str, len);
583 return pmlen + len - 1;
587 int POOL_MEM::strcpy(const char *str)
589 int len = strlen(str) + 1;
591 memcpy(mem, str, len);