2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula memory pool routines.
23 * The idea behind these routines is that there will be
24 * pools of memory that are pre-allocated for quick
25 * access. The pools will have a fixed memory size on allocation
26 * but if need be, the size can be increased. This is
27 * particularly useful for filename
28 * buffers where 256 bytes should be sufficient in 99.99%
29 * of the cases, but when it isn't we want to be able to
32 * A major advantage of the pool memory aside from the speed
33 * is that the buffer carrys around its size, so to ensure that
34 * there is enough memory, simply call the check_pool_memory_size()
35 * with the desired size and it will adjust only if necessary.
42 #define dbglvl DT_MEMORY|800
44 #ifdef HAVE_MALLOC_TRIM
45 extern "C" int malloc_trim (size_t pad);
49 int32_t size; /* default size */
50 int32_t max_allocated; /* max allocated */
51 int32_t max_used; /* max buffers used */
52 int32_t in_use; /* number in use */
53 struct abufhead *free_buf; /* pointer to free buffers */
56 /* Bacula Name length plus extra */
57 #define NLEN (MAX_NAME_LENGTH+2)
59 /* #define STRESS_TEST_POOL */
60 #ifndef STRESS_TEST_POOL
62 * Define default Pool buffer sizes
64 static struct s_pool_ctl pool_ctl[] = {
65 { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */
66 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
67 { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */
68 { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */
69 { 1024, 1024, 0, 0, NULL }, /* PM_EMSG error message buffer */
70 { 4096, 4096, 0, 0, NULL } /* PM_BSOCK message buffer */
74 /* This is used ONLY when stress testing the code */
75 static struct s_pool_ctl pool_ctl[] = {
76 { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */
77 { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */
78 { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */
79 { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */
80 { 20, 20, 0, 0, NULL }, /* PM_EMSG error message buffer */
81 { 20, 20, 0, 0, NULL } /* PM_BSOCK message buffer */
86 /* Memory allocation control structures and storage. */
88 int32_t ablen; /* Buffer length in bytes */
89 int32_t pool; /* pool */
90 struct abufhead *next; /* pointer to next free buffer */
91 int32_t bnet_size; /* dummy for bnet_send() */
92 int32_t bnet_extension; /* dummy for bnet extension */
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(dbglvl, "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(dbglvl, "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 /* Disabled because it hangs in #5507 */
217 struct abufhead *next;
218 /* Don't let him free the same buffer twice */
219 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
221 Dmsg4(dbglvl, "free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
222 Dmsg4(dbglvl, "bad free_pool_memory %p pool=%d from %s:%d\n", buf, pool, fname, lineno);
223 V(mutex); /* unblock the pool */
224 ASSERT(next != buf); /* attempt to free twice */
228 buf->next = pool_ctl[pool].free_buf;
229 pool_ctl[pool].free_buf = buf;
231 Dmsg4(dbglvl, "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);
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;
295 /* Realloc pool memory buffer */
296 POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size)
298 char *cp = (char *)obuf;
305 buf = realloc(cp, size+HEAD_SIZE);
308 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
310 ((struct abufhead *)buf)->ablen = size;
311 pool = ((struct abufhead *)buf)->pool;
312 if (size > pool_ctl[pool].max_allocated) {
313 pool_ctl[pool].max_allocated = size;
316 return (POOLMEM *)(((char *)buf)+HEAD_SIZE);
319 POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size)
322 if (size <= sizeof_pool_memory(obuf)) {
325 return realloc_pool_memory(obuf, size);
328 /* Free a memory buffer */
329 void free_pool_memory(POOLMEM *obuf)
331 struct abufhead *buf;
336 buf = (struct abufhead *)((char *)obuf - HEAD_SIZE);
338 pool_ctl[pool].in_use--;
340 free((char *)buf); /* free nonpooled memory */
341 } else { /* otherwise link it to the free pool chain */
343 struct abufhead *next;
344 /* Don't let him free the same buffer twice */
345 for (next=pool_ctl[pool].free_buf; next; next=next->next) {
348 ASSERT(next != buf); /* attempt to free twice */
352 buf->next = pool_ctl[pool].free_buf;
353 pool_ctl[pool].free_buf = buf;
355 Dmsg2(dbglvl, "free_pool_memory %p pool=%d\n", buf, pool);
358 #endif /* SMARTALLOC */
361 * Clean up memory pool periodically
364 static time_t last_garbage_collection = 0;
365 const int garbage_interval = 24 * 60 * 60; /* garbage collect every 24 hours */
367 void garbage_collect_memory_pool()
371 Dmsg0(200, "garbage collect memory pool\n");
373 if (last_garbage_collection == 0) {
374 last_garbage_collection = time(NULL);
379 if (now >= last_garbage_collection + garbage_interval) {
380 last_garbage_collection = now;
382 garbage_collect_memory();
388 /* Release all freed pooled memory */
389 void close_memory_pool()
391 struct abufhead *buf, *next;
396 sm_check(__FILE__, __LINE__, false);
398 for (int i=1; i<=PM_MAX; i++) {
399 buf = pool_ctl[i].free_buf;
403 bytes += sizeof_pool_memory((char *)buf);
407 pool_ctl[i].free_buf = NULL;
409 Dmsg2(DT_MEMORY|001, "Freed mem_pool count=%d size=%s\n", count, edit_uint64_with_commas(bytes, ed1));
410 if (chk_dbglvl(DT_MEMORY|1)) {
411 print_memory_pool_stats();
418 * Garbage collect and trim memory if possible
419 * This should be called after all big memory usages
422 void garbage_collect_memory()
424 close_memory_pool(); /* release free chain */
425 #ifdef HAVE_MALLOC_TRIM
433 static const char *pool_name(int pool)
435 static const char *name[] = {"NoPool", "NAME ", "FNAME ", "MSG ", "EMSG ", "BSOCK "};
438 if (pool >= 0 && pool <= PM_MAX) {
441 sprintf(buf, "%-6d", pool);
445 /* Print staticstics on memory pool usage
447 void print_memory_pool_stats()
449 Pmsg0(-1, "Pool Maxsize Maxused Inuse\n");
450 for (int i=0; i<=PM_MAX; i++)
451 Pmsg4(-1, "%5s %7d %7d %5d\n", pool_name(i), pool_ctl[i].max_allocated,
452 pool_ctl[i].max_used, pool_ctl[i].in_use);
458 void print_memory_pool_stats() {}
462 * Concatenate a string (str) onto a pool memory buffer pm
463 * Returns: length of concatenated string
465 int pm_strcat(POOLMEM **pm, const char *str)
467 int pmlen = strlen(*pm);
472 len = strlen(str) + 1;
473 *pm = check_pool_memory_size(*pm, pmlen + len);
474 memcpy(*pm+pmlen, str, len);
475 return pmlen + len - 1;
478 int pm_strcat(POOLMEM *&pm, const char *str)
480 int pmlen = strlen(pm);
485 len = strlen(str) + 1;
486 pm = check_pool_memory_size(pm, pmlen + len);
487 memcpy(pm+pmlen, str, len);
488 return pmlen + len - 1;
491 int pm_strcat(POOLMEM *&pm, POOL_MEM &str)
493 int pmlen = strlen(pm);
494 int len = strlen(str.c_str()) + 1;
496 pm = check_pool_memory_size(pm, pmlen + len);
497 memcpy(pm+pmlen, str.c_str(), len);
498 return pmlen + len - 1;
501 int pm_strcat(POOL_MEM &pm, const char *str)
503 int pmlen = strlen(pm.c_str());
508 len = strlen(str) + 1;
509 pm.check_size(pmlen + len);
510 memcpy(pm.c_str()+pmlen, str, len);
511 return pmlen + len - 1;
515 * Copy a string (str) into a pool memory buffer pm
516 * Returns: length of string copied
518 int pm_strcpy(POOLMEM **pm, const char *str)
524 len = strlen(str) + 1;
525 *pm = check_pool_memory_size(*pm, len);
526 memcpy(*pm, str, len);
530 int pm_strcpy(POOLMEM *&pm, const char *str)
536 len = strlen(str) + 1;
537 pm = check_pool_memory_size(pm, len);
538 memcpy(pm, str, len);
542 int pm_strcpy(POOLMEM *&pm, POOL_MEM &str)
544 int len = strlen(str.c_str()) + 1;
546 pm = check_pool_memory_size(pm, len);
547 memcpy(pm, str.c_str(), len);
551 int pm_strcpy(POOL_MEM &pm, const char *str)
557 len = strlen(str) + 1;
559 memcpy(pm.c_str(), str, len);
564 * Copy data into a pool memory buffer pm
565 * Returns: length of data copied
567 int pm_memcpy(POOLMEM **pm, const char *data, int32_t n)
569 *pm = check_pool_memory_size(*pm, n);
570 memcpy(*pm, data, n);
574 int pm_memcpy(POOLMEM *&pm, const char *data, int32_t n)
576 pm = check_pool_memory_size(pm, n);
581 int pm_memcpy(POOLMEM *&pm, POOL_MEM &data, int32_t n)
583 pm = check_pool_memory_size(pm, n);
584 memcpy(pm, data.c_str(), n);
588 int pm_memcpy(POOL_MEM &pm, const char *data, int32_t n)
591 memcpy(pm.c_str(), data, n);
595 /* ============== CLASS POOL_MEM ============== */
597 /* Return the size of a memory buffer */
598 int32_t POOL_MEM::max_size()
603 size = ((struct abufhead *)cp)->ablen;
604 Dmsg1(900, "max_size=%d\n", size);
608 void POOL_MEM::realloc_pm(int32_t size)
616 buf = (char *)realloc(cp, size+HEAD_SIZE);
619 Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), size);
621 Dmsg2(900, "Old buf=%p new buf=%p\n", cp, buf);
622 ((struct abufhead *)buf)->ablen = size;
623 pool = ((struct abufhead *)buf)->pool;
624 if (size > pool_ctl[pool].max_allocated) {
625 pool_ctl[pool].max_allocated = size;
629 Dmsg3(900, "Old buf=%p new buf=%p mem=%p\n", cp, buf, mem);
632 int POOL_MEM::strcat(const char *str)
634 int pmlen = strlen(mem);
639 len = strlen(str) + 1;
640 check_size(pmlen + len);
641 memcpy(mem+pmlen, str, len);
642 return pmlen + len - 1;
645 int POOL_MEM::strcpy(const char *str)
651 len = strlen(str) + 1;
653 memcpy(mem, str, len);