X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fmem_pool.c;h=b1f849fef94345db8e53d70321e6d65701158c33;hb=5fab1f6fa93fa0b2c8248c055d5b77a09e1dbab7;hp=9eddd47ad156afabba40afea7dd2abe085e33a68;hpb=b5752d5d38754259dc2bb30e1461ae0431c2333d;p=bacula%2Fbacula diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 9eddd47ad1..b1f849fef9 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -21,7 +21,7 @@ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -43,23 +43,44 @@ #include "bacula.h" struct s_pool_ctl { - size_t size; /* default size */ - size_t max_size; /* max allocated */ - size_t max_used; /* max buffers used */ - size_t in_use; /* number in use */ + int32_t size; /* default size */ + int32_t max_size; /* max allocated */ + int32_t max_used; /* max buffers used */ + int32_t in_use; /* number in use */ struct abufhead *free_buf; /* pointer to free buffers */ }; +/* Bacula Name length plus extra */ +#define NLEN (MAX_NAME_LENGTH+2) + +/* #define STRESS_TEST_POOL */ +#ifndef STRESS_TEST_POOL +/* + * Define default Pool buffer sizes + */ static struct s_pool_ctl pool_ctl[] = { { 256, 256, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ { 256, 256, 0, 0, NULL }, /* PM_FNAME filename buffers */ { 512, 512, 0, 0, NULL }, /* PM_MESSAGE message buffer */ { 1024, 1024, 0, 0, NULL } /* PM_EMSG error message buffer */ }; +#else + +/* This is used ONLY when stress testing the code */ +static struct s_pool_ctl pool_ctl[] = { + { 20, 20, 0, 0, NULL }, /* PM_NOPOOL no pooling */ + { NLEN, NLEN,0, 0, NULL }, /* PM_NAME Bacula name */ + { 20, 20, 0, 0, NULL }, /* PM_FNAME filename buffers */ + { 20, 20, 0, 0, NULL }, /* PM_MESSAGE message buffer */ + { 20, 20, 0, 0, NULL } /* PM_EMSG error message buffer */ +}; +#endif + /* Memory allocation control structures and storage. */ struct abufhead { - size_t ablen; /* Buffer length in bytes */ + int32_t ablen; /* Buffer length in bytes */ int32_t pool; /* pool */ struct abufhead *next; /* pointer to next free buffer */ }; @@ -71,13 +92,10 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #define HEAD_SIZE BALIGN(sizeof(struct abufhead)) -extern POOLMEM *sm_malloc(char *fname, int lineno, int nbytes); - POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool) { struct abufhead *buf; - sm_check(fname, lineno, True); if (pool > PM_MAX) { Emsg2(M_ABORT, 0, "MemPool index %d larger than max %d\n", pool, PM_MAX); } @@ -90,12 +108,12 @@ POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool) pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); - Dmsg3(150, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno); + Dmsg3(300, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno); sm_new_owner(fname, lineno, (char *)buf); return (POOLMEM *)((char *)buf+HEAD_SIZE); } - if ((buf = (struct abufhead *) sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) { + if ((buf = (struct abufhead *)sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) { V(mutex); Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", pool_ctl[pool].size); } @@ -106,17 +124,16 @@ POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool) pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); - Dmsg3(150, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno); + Dmsg3(300, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno); return (POOLMEM *)((char *)buf+HEAD_SIZE); } /* Get nonpool memory of size requested */ -POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) +POOLMEM *sm_get_memory(char *fname, int lineno, int32_t size) { struct abufhead *buf; int pool = 0; - sm_check(fname, lineno, True); if ((buf = (struct abufhead *) sm_malloc(fname, lineno, size+HEAD_SIZE)) == NULL) { Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); } @@ -129,8 +146,87 @@ POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } + +/* Return the size of a memory buffer */ +int32_t sm_sizeof_pool_memory(char *fname, int lineno, POOLMEM *obuf) +{ + char *cp = (char *)obuf; + + ASSERT(obuf); + cp -= HEAD_SIZE; + return ((struct abufhead *)cp)->ablen; +} + +/* Realloc pool memory buffer */ +POOLMEM *sm_realloc_pool_memory(char *fname, int lineno, POOLMEM *obuf, int32_t size) +{ + char *cp = (char *)obuf; + void *buf; + int pool; + + ASSERT(obuf); + P(mutex); + cp -= HEAD_SIZE; + buf = sm_realloc(fname, lineno, cp, size+HEAD_SIZE); + if (buf == NULL) { + V(mutex); + Emsg1(M_ABORT, 0, "Out of memory requesting %d bytes\n", size); + } + ((struct abufhead *)buf)->ablen = size; + pool = ((struct abufhead *)buf)->pool; + if (size > pool_ctl[pool].max_size) { + pool_ctl[pool].max_size = size; + } + V(mutex); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); +} + +POOLMEM *sm_check_pool_memory_size(char *fname, int lineno, POOLMEM *obuf, int32_t size) +{ + ASSERT(obuf); + if (size <= sizeof_pool_memory(obuf)) { + return obuf; + } + return realloc_pool_memory(obuf, size); +} + +/* Free a memory buffer */ +void sm_free_pool_memory(char *fname, int lineno, POOLMEM *obuf) +{ + struct abufhead *buf; + int pool; + + ASSERT(obuf); + P(mutex); + buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); + pool = buf->pool; + pool_ctl[pool].in_use--; + if (pool == 0) { + free((char *)buf); /* free nonpooled memory */ + } else { /* otherwise link it to the free pool chain */ +#ifdef DEBUG + struct abufhead *next; + /* Don't let him free the same buffer twice */ + for (next=pool_ctl[pool].free_buf; next; next=next->next) { + if (next == buf) { + Dmsg4(300, "bad free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno); + V(mutex); /* unblock the pool */ + ASSERT(next != buf); /* attempt to free twice */ + } + } +#endif + buf->next = pool_ctl[pool].free_buf; + pool_ctl[pool].free_buf = buf; + } + Dmsg4(300, "free_pool_memory %x pool=%d from %s:%d\n", buf, pool, fname, lineno); + V(mutex); +} + + #else +/* =================================================================== */ + POOLMEM *get_pool_memory(int pool) { struct abufhead *buf; @@ -159,7 +255,7 @@ POOLMEM *get_pool_memory(int pool) } /* Get nonpool memory of size requested */ -POOLMEM *get_memory(size_t size) +POOLMEM *get_memory(int32_t size) { struct abufhead *buf; int pool = 0; @@ -176,52 +272,25 @@ POOLMEM *get_memory(size_t size) } return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -#endif /* SMARTALLOC */ - - - -/* Free a memory buffer */ -void free_pool_memory(POOLMEM *obuf) -{ - struct abufhead *buf; - int pool; - - sm_check(__FILE__, __LINE__, False); - ASSERT(obuf); - P(mutex); - buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); - pool = buf->pool; - pool_ctl[pool].in_use--; - if (pool == 0) { - free((char *)buf); /* free nonpooled memory */ - } else { /* otherwise link it to the free pool chain */ - buf->next = pool_ctl[pool].free_buf; - pool_ctl[pool].free_buf = buf; - } - Dmsg2(150, "free_pool_memory %x pool=%d\n", buf, pool); - V(mutex); -} /* Return the size of a memory buffer */ -size_t sizeof_pool_memory(POOLMEM *obuf) +int32_t sizeof_pool_memory(POOLMEM *obuf) { char *cp = (char *)obuf; - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); cp -= HEAD_SIZE; return ((struct abufhead *)cp)->ablen; } /* Realloc pool memory buffer */ -POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) +POOLMEM *realloc_pool_memory(POOLMEM *obuf, int32_t size) { char *cp = (char *)obuf; void *buf; int pool; - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); P(mutex); cp -= HEAD_SIZE; @@ -236,13 +305,11 @@ POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) pool_ctl[pool].max_size = size; } V(mutex); - sm_check(__FILE__, __LINE__, False); return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) +POOLMEM *check_pool_memory_size(POOLMEM *obuf, int32_t size) { - sm_check(__FILE__, __LINE__, False); ASSERT(obuf); if (size <= sizeof_pool_memory(obuf)) { return obuf; @@ -250,6 +317,44 @@ POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) return realloc_pool_memory(obuf, size); } +/* Free a memory buffer */ +void free_pool_memory(POOLMEM *obuf) +{ + struct abufhead *buf; + int pool; + + ASSERT(obuf); + P(mutex); + buf = (struct abufhead *)((char *)obuf - HEAD_SIZE); + pool = buf->pool; + pool_ctl[pool].in_use--; + if (pool == 0) { + free((char *)buf); /* free nonpooled memory */ + } else { /* otherwise link it to the free pool chain */ +#ifdef DEBUG + struct abufhead *next; + /* Don't let him free the same buffer twice */ + for (next=pool_ctl[pool].free_buf; next; next=next->next) { + if (next == buf) { + V(mutex); + ASSERT(next != buf); /* attempt to free twice */ + } + } +#endif + buf->next = pool_ctl[pool].free_buf; + pool_ctl[pool].free_buf = buf; + } + Dmsg2(300, "free_pool_memory %x pool=%d\n", buf, pool); + V(mutex); +} + +#endif /* SMARTALLOC */ + + + + + + /* Release all pooled memory */ void close_memory_pool() {