summaryrefslogtreecommitdiffstats
path: root/framework/src/suricata/src/util-pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/suricata/src/util-pool.c')
-rw-r--r--framework/src/suricata/src/util-pool.c737
1 files changed, 0 insertions, 737 deletions
diff --git a/framework/src/suricata/src/util-pool.c b/framework/src/suricata/src/util-pool.c
deleted file mode 100644
index 6f405252..00000000
--- a/framework/src/suricata/src/util-pool.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/* Copyright (C) 2007-2010 Open Information Security Foundation
- *
- * You can copy, redistribute or modify this Program under the terms of
- * the GNU General Public License version 2 as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/**
- * \defgroup utilpool Pool
- *
- * ::Pool are an effective way to maintain a set of ready to use
- * structures.
- *
- * To create a ::Pool, you need to use PoolInit(). You can
- * get an item from the ::Pool by using PoolGet(). When you're
- * done with it call PoolReturn().
- * To destroy the ::Pool, call PoolFree(), it will free all used
- * memory.
- *
- * @{
- */
-
-/**
- * \file
- *
- * \author Victor Julien <victor@inliniac.net>
- *
- * Pool utility functions
- */
-
-#include "suricata-common.h"
-#include "util-pool.h"
-#include "util-pool-thread.h"
-#include "util-unittest.h"
-#include "util-debug.h"
-
-static int PoolMemset(void *pitem, void *initdata)
-{
- Pool *p = (Pool *) initdata;
-
- memset(pitem, 0, p->elt_size);
- return 1;
-}
-
-/**
- * \brief Check if data is preallocated
- * \retval 0 or -1 if not inside */
-static int PoolDataPreAllocated(Pool *p, void *data)
-{
- int delta = data - p->data_buffer;
- if ((delta < 0) || (delta > p->data_buffer_size)) {
- return 0;
- }
- return 1;
-}
-
-/** \brief Init a Pool
- *
- * PoolInit() creates a ::Pool. The Alloc function must only do
- * allocation stuff. The Cleanup function must not try to free
- * the PoolBucket::data. This is done by the ::Pool management
- * system.
- *
- * \param size
- * \param prealloc_size
- * \param elt_size Memory size of an element
- * \param Alloc An allocation function or NULL to use a standard SCMalloc
- * \param Init An init function or NULL to use a standard memset to 0
- * \param InitData Init data
- * \param Cleanup a free function or NULL if no special treatment is needed
- * \param Free free func
- * \retval the allocated Pool
- */
-Pool *PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *))
-{
- Pool *p = NULL;
-
- if (size != 0 && prealloc_size > size) {
- SCLogError(SC_ERR_POOL_INIT, "size error");
- goto error;
- }
- if (size != 0 && elt_size == 0) {
- SCLogError(SC_ERR_POOL_INIT, "size != 0 && elt_size == 0");
- goto error;
- }
- if (elt_size && Free) {
- SCLogError(SC_ERR_POOL_INIT, "elt_size && Free");
- goto error;
- }
-
- /* setup the filter */
- p = SCMalloc(sizeof(Pool));
- if (unlikely(p == NULL)) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- goto error;
- }
-
- memset(p,0,sizeof(Pool));
-
- p->max_buckets = size;
- p->preallocated = prealloc_size;
- p->elt_size = elt_size;
- p->data_buffer_size = prealloc_size * elt_size;
- p->Alloc = Alloc;
- p->Init = Init;
- p->InitData = InitData;
- p->Cleanup = Cleanup;
- p->Free = Free;
- if (p->Init == NULL) {
- p->Init = PoolMemset;
- p->InitData = p;
- }
-
- /* alloc the buckets and place them in the empty list */
- uint32_t u32 = 0;
- if (size > 0) {
- PoolBucket *pb = SCCalloc(size, sizeof(PoolBucket));
- if (unlikely(pb == NULL)) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- goto error;
- }
- p->pb_buffer = pb;
- memset(pb, 0, size * sizeof(PoolBucket));
- for (u32 = 0; u32 < size; u32++) {
- /* populate pool */
- pb->next = p->empty_stack;
- pb->flags |= POOL_BUCKET_PREALLOCATED;
- p->empty_stack = pb;
- p->empty_stack_size++;
- pb++;
- }
- }
-
- if (size > 0) {
- p->data_buffer = SCCalloc(prealloc_size, elt_size);
- /* FIXME better goto */
- if (p->data_buffer == NULL) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- goto error;
- }
- }
- /* prealloc the buckets and requeue them to the alloc list */
- for (u32 = 0; u32 < prealloc_size; u32++) {
- if (size == 0) { /* unlimited */
- PoolBucket *pb = SCMalloc(sizeof(PoolBucket));
- if (unlikely(pb == NULL)) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- goto error;
- }
-
- memset(pb, 0, sizeof(PoolBucket));
-
- if (p->Alloc) {
- pb->data = p->Alloc();
- } else {
- pb->data = SCMalloc(p->elt_size);
- }
- if (pb->data == NULL) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- SCFree(pb);
- goto error;
- }
- if (p->Init(pb->data, p->InitData) != 1) {
- SCLogError(SC_ERR_POOL_INIT, "init error");
- if (p->Cleanup)
- p->Cleanup(pb->data);
- if (p->Free)
- p->Free(pb->data);
- else
- SCFree(pb->data);
- SCFree(pb);
- goto error;
- }
- p->allocated++;
-
- pb->next = p->alloc_stack;
- p->alloc_stack = pb;
- p->alloc_stack_size++;
- } else {
- PoolBucket *pb = p->empty_stack;
- if (pb == NULL) {
- SCLogError(SC_ERR_POOL_INIT, "alloc error");
- goto error;
- }
-
- pb->data = (char *)p->data_buffer + u32 * elt_size;
- if (p->Init(pb->data, p->InitData) != 1) {
- SCLogError(SC_ERR_POOL_INIT, "init error");
- if (p->Cleanup)
- p->Cleanup(pb->data);
- goto error;
- }
-
- p->empty_stack = pb->next;
- p->empty_stack_size--;
-
- p->allocated++;
-
- pb->next = p->alloc_stack;
- p->alloc_stack = pb;
- p->alloc_stack_size++;
- }
- }
-
- return p;
-
-error:
- if (p != NULL) {
- PoolFree(p);
- }
- return NULL;
-}
-
-
-void PoolFree(Pool *p)
-{
- if (p == NULL)
- return;
-
- while (p->alloc_stack != NULL) {
- PoolBucket *pb = p->alloc_stack;
- p->alloc_stack = pb->next;
- if (p->Cleanup)
- p->Cleanup(pb->data);
- if (PoolDataPreAllocated(p, pb->data) == 0) {
- if (p->Free)
- p->Free(pb->data);
- else
- SCFree(pb->data);
- }
- pb->data = NULL;
- if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
- SCFree(pb);
- }
- }
-
- while (p->empty_stack != NULL) {
- PoolBucket *pb = p->empty_stack;
- p->empty_stack = pb->next;
- if (pb->data!= NULL) {
- if (p->Cleanup)
- p->Cleanup(pb->data);
- if (PoolDataPreAllocated(p, pb->data) == 0) {
- if (p->Free)
- p->Free(pb->data);
- else
- SCFree(pb->data);
- }
- pb->data = NULL;
- }
- if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
- SCFree(pb);
- }
- }
-
- if (p->pb_buffer)
- SCFree(p->pb_buffer);
- if (p->data_buffer)
- SCFree(p->data_buffer);
- SCFree(p);
-}
-
-void PoolPrint(Pool *p)
-{
- printf("\n----------- Hash Table Stats ------------\n");
- printf("Buckets: %" PRIu32 "\n", p->empty_stack_size + p->alloc_stack_size);
- printf("-----------------------------------------\n");
-}
-
-void *PoolGet(Pool *p)
-{
- SCEnter();
-
- PoolBucket *pb = p->alloc_stack;
- if (pb != NULL) {
- /* pull from the alloc list */
- p->alloc_stack = pb->next;
- p->alloc_stack_size--;
-
- /* put in the empty list */
- pb->next = p->empty_stack;
- p->empty_stack = pb;
- p->empty_stack_size++;
- } else {
- if (p->max_buckets == 0 || p->allocated < p->max_buckets) {
- void *pitem;
- SCLogDebug("max_buckets %"PRIu32"", p->max_buckets);
-
- if (p->Alloc != NULL) {
- pitem = p->Alloc();
- } else {
- pitem = SCMalloc(p->elt_size);
- }
-
- if (pitem != NULL) {
- if (p->Init(pitem, p->InitData) != 1) {
- if (p->Cleanup)
- p->Cleanup(pitem);
- if (p->Free != NULL)
- p->Free(pitem);
- else
- SCFree(pitem);
- SCReturnPtr(NULL, "void");
- }
-
- p->allocated++;
-
- p->outstanding++;
- if (p->outstanding > p->max_outstanding)
- p->max_outstanding = p->outstanding;
- }
-
- SCReturnPtr(pitem, "void");
- } else {
- SCReturnPtr(NULL, "void");
- }
- }
-
- void *ptr = pb->data;
- pb->data = NULL;
- p->outstanding++;
- if (p->outstanding > p->max_outstanding)
- p->max_outstanding = p->outstanding;
- SCReturnPtr(ptr,"void");
-}
-
-void PoolReturn(Pool *p, void *data)
-{
- SCEnter();
-
- PoolBucket *pb = p->empty_stack;
-
- SCLogDebug("pb %p", pb);
-
- if (pb == NULL) {
- p->allocated--;
- p->outstanding--;
- if (p->Cleanup != NULL) {
- p->Cleanup(data);
- }
- if (PoolDataPreAllocated(p, data) == 0) {
- if (p->Free)
- p->Free(data);
- else
- SCFree(data);
- }
-
- SCLogDebug("tried to return data %p to the pool %p, but no more "
- "buckets available. Just freeing the data.", data, p);
- SCReturn;
- }
-
- /* pull from the alloc list */
- p->empty_stack = pb->next;
- p->empty_stack_size--;
-
- /* put in the alloc list */
- pb->next = p->alloc_stack;
- p->alloc_stack = pb;
- p->alloc_stack_size++;
-
- pb->data = data;
- p->outstanding--;
- SCReturn;
-}
-
-void PoolPrintSaturation(Pool *p)
-{
- SCLogDebug("pool %p is using %"PRIu32" out of %"PRIu32" items (%02.1f%%), max %"PRIu32" (%02.1f%%): pool struct memory %"PRIu64".", p, p->outstanding, p->max_buckets, (float)(p->outstanding/(float)(p->max_buckets))*100, p->max_outstanding, (float)(p->max_outstanding/(float)(p->max_buckets))*100, (uint64_t)(p->max_buckets * sizeof(PoolBucket)));
-}
-
-/*
- * ONLY TESTS BELOW THIS COMMENT
- */
-
-void *PoolTestAlloc()
-{
- void *ptr = SCMalloc(10);
- if (unlikely(ptr == NULL))
- return NULL;
- return ptr;
-}
-int PoolTestInitArg(void *data, void *allocdata)
-{
- size_t len = strlen((char *)allocdata) + 1;
- char *str = data;
- if (str != NULL)
- strlcpy(str,(char *)allocdata,len);
- return 1;
-}
-
-void PoolTestFree(void *ptr)
-{
- return;
-}
-
-#ifdef UNITTESTS
-static int PoolTestInit01 (void)
-{
- Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
- if (p == NULL)
- return 0;
-
- PoolFree(p);
- return 1;
-}
-
-static int PoolTestInit02 (void)
-{
- int retval = 0;
-
- Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- if (p->alloc_stack == NULL || p->empty_stack == NULL) {
- printf("list(s) not properly initialized (a:%p e:%p): ",
- p->alloc_stack, p->empty_stack);
- retval = 0;
- goto end;
- }
-
- if (p->Alloc != PoolTestAlloc) {
- printf("Alloc func ptr %p != %p: ",
- p->Alloc, PoolTestAlloc);
- retval = 0;
- goto end;
- }
-
- if (p->Cleanup != PoolTestFree) {
- printf("Free func ptr %p != %p: ",
- p->Cleanup, PoolTestFree);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-
-static int PoolTestInit03 (void)
-{
- int retval = 0;
- void *data = NULL;
-
- Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- data = PoolGet(p);
- if (data == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (p->alloc_stack_size != 4) {
- printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- if (p->empty_stack_size != 6) {
- printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-
-static int PoolTestInit04 (void)
-{
- int retval = 0;
- char *str = NULL;
-
- Pool *p = PoolInit(10,5,strlen("test") + 1,NULL, PoolTestInitArg,(void *)"test",PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- str = PoolGet(p);
- if (str == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (strcmp(str, "test") != 0) {
- printf("Memory not properly initialized: ");
- retval = 0;
- goto end;
- }
-
- if (p->alloc_stack_size != 4) {
- printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- if (p->empty_stack_size != 6) {
- printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-
-static int PoolTestInit05 (void)
-{
- int retval = 0;
- void *data = NULL;
-
- Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL, NULL,PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- data = PoolGet(p);
- if (data == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (p->alloc_stack_size != 4) {
- printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- if (p->empty_stack_size != 6) {
- printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
- retval = 0;
- goto end;
- }
-
- PoolReturn(p, data);
- data = NULL;
-
- if (p->alloc_stack_size != 5) {
- printf("p->alloc_stack_size 5 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- if (p->empty_stack_size != 5) {
- printf("p->empty_stack_size 5 != %" PRIu32 ": ", p->empty_stack_size);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-
-static int PoolTestInit06 (void)
-{
- int retval = 0;
- void *data = NULL;
- void *data2 = NULL;
-
- Pool *p = PoolInit(1,0,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- if (p->allocated != 0) {
- printf("p->allocated 0 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- data = PoolGet(p);
- if (data == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (p->allocated != 1) {
- printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- data2 = PoolGet(p);
- if (data2 != NULL) {
- printf("PoolGet returned %p, expected NULL: ", data2);
- retval = 0;
- goto end;
- }
-
- PoolReturn(p,data);
- data = NULL;
-
- if (p->allocated != 1) {
- printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- if (p->alloc_stack_size != 1) {
- printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-
-/** \test pool with unlimited size */
-static int PoolTestInit07 (void)
-{
- int retval = 0;
- void *data = NULL;
- void *data2 = NULL;
-
- Pool *p = PoolInit(0,1,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
- if (p == NULL)
- goto end;
-
- if (p->max_buckets != 0) {
- printf("p->max_buckets 0 != %" PRIu32 ": ", p->max_buckets);
- retval = 0;
- goto end;
- }
-
- if (p->allocated != 1) {
- printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- data = PoolGet(p);
- if (data == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (p->allocated != 1) {
- printf("(2) p->allocated 1 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- data2 = PoolGet(p);
- if (data2 == NULL) {
- printf("PoolGet returned NULL: ");
- retval = 0;
- goto end;
- }
-
- if (p->allocated != 2) {
- printf("(3) p->allocated 2 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- PoolReturn(p,data);
- data = NULL;
-
- if (p->allocated != 2) {
- printf("(4) p->allocated 2 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- if (p->alloc_stack_size != 1) {
- printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size);
- retval = 0;
- goto end;
- }
-
- PoolReturn(p,data2);
- data2 = NULL;
-
- if (p->allocated != 1) {
- printf("(5) p->allocated 1 != %" PRIu32 ": ", p->allocated);
- retval = 0;
- goto end;
- }
-
- retval = 1;
-end:
- if (p != NULL)
- PoolFree(p);
- return retval;
-}
-#endif /* UNITTESTS */
-
-void PoolRegisterTests(void)
-{
-#ifdef UNITTESTS
- UtRegisterTest("PoolTestInit01", PoolTestInit01, 1);
- UtRegisterTest("PoolTestInit02", PoolTestInit02, 1);
- UtRegisterTest("PoolTestInit03", PoolTestInit03, 1);
- UtRegisterTest("PoolTestInit04", PoolTestInit04, 1);
- UtRegisterTest("PoolTestInit05", PoolTestInit05, 1);
- UtRegisterTest("PoolTestInit06", PoolTestInit06, 1);
- UtRegisterTest("PoolTestInit07", PoolTestInit07, 1);
-
- PoolThreadRegisterTests();
-#endif /* UNITTESTS */
-}
-
-
-/**
- * @}
- */