]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pool: realize a block allocation for preallocated item.
authorEric Leblond <eric@regit.org>
Wed, 29 Aug 2012 10:27:26 +0000 (12:27 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 3 Sep 2012 14:20:32 +0000 (16:20 +0200)
This patch required a evolution of Pool API as it is needed to
proceed to alloc or init separetely. The PoolInit has been changed
with a new Init function parameter.

src/app-layer-parser.c
src/defrag.c
src/stream-tcp-reassemble.c
src/stream-tcp.c
src/stream.c
src/util-pool.c
src/util-pool.h

index e5ac4694b8ea31a90c120bb1dd65f4764a173ea6..c18c0617cf118ec4d35595631d6e13f7be206b2b 100644 (file)
@@ -98,15 +98,15 @@ FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
 }
 
 /** \brief Alloc a AppLayerParserResultElmt func for the pool */
-static void *AlpResultElmtPoolAlloc(void *null)
+static void *AlpResultElmtPoolAlloc()
 {
-    AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)SCMalloc
-                                    (sizeof(AppLayerParserResultElmt));
+    AppLayerParserResultElmt *e = NULL;
+
+    e = (AppLayerParserResultElmt *)SCMalloc
+        (sizeof(AppLayerParserResultElmt));
     if (e == NULL)
         return NULL;
 
-    memset(e, 0, sizeof(AppLayerParserResultElmt));
-
 #ifdef DEBUG
     al_result_pool_elmts++;
     SCLogDebug("al_result_pool_elmts %"PRIu32"", al_result_pool_elmts);
@@ -122,7 +122,6 @@ static void AlpResultElmtPoolFree(void *e)
         if (re->data_ptr != NULL)
             SCFree(re->data_ptr);
     }
-    SCFree(re);
 
 #ifdef DEBUG
     al_result_pool_elmts--;
@@ -1335,7 +1334,9 @@ void RegisterAppLayerParsers(void)
 
     /** setup result pool
      * \todo Per thread pool */
-    al_result_pool = PoolInit(1000,250,AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);
+    al_result_pool = PoolInit(1000, 250,
+            sizeof(AppLayerParserResultElmt),
+            AlpResultElmtPoolAlloc, NULL, NULL, AlpResultElmtPoolFree);
 
     RegisterHTPParsers();
     RegisterSSLParsers();
index 816e365c3b3d524dbb13ce133be7068b603b4cbd..d26dfd57a7daa7fd3d65f673f5433a3fe475b665 100644 (file)
@@ -303,28 +303,16 @@ DefragFragReset(Frag *frag)
 /**
  * \brief Allocate a new frag for use in a pool.
  */
-static void *
-DefragFragNew(void *arg)
+static int
+DefragFragInit(void *data, void *initdata)
 {
-    DefragContext *dc = arg;
-    Frag *frag;
+    DefragContext *dc = initdata;
+    Frag *frag = data;
 
-    frag = SCCalloc(1, sizeof(*frag));
-    if (frag == NULL)
-        return NULL;
+    memset(frag, 0, sizeof(*frag));
     frag->dc = dc;
 
-    return (void *)frag;
-}
-
-/**
- * \brief Free a frag when released from a pool.
- */
-static void
-DefragFragFree(void *arg)
-{
-    Frag *frag = arg;
-    SCFree(frag);
+    return 1;
 }
 
 /**
@@ -369,23 +357,20 @@ DefragTrackerReset(DefragTracker *tracker)
  *
  * \retval A new DefragTracker if successfull, NULL on failure.
  */
-static void *
-DefragTrackerNew(void *arg)
+static int
+DefragTrackerInit(void *data, void *initdata)
 {
-    DefragContext *dc = arg;
-    DefragTracker *tracker;
+    DefragContext *dc = initdata;
+    DefragTracker *tracker = data;
 
-    tracker = SCCalloc(1, sizeof(*tracker));
-    if (tracker == NULL)
-        return NULL;
+    memset(tracker, 0, sizeof(*tracker));
     if (SCMutexInit(&tracker->lock, NULL) != 0) {
-        SCFree(tracker);
-        return NULL;
+        return 0;
     }
     tracker->dc = dc;
     TAILQ_INIT(&tracker->frags);
 
-    return (void *)tracker;
+    return 1;
 }
 
 /**
@@ -399,7 +384,6 @@ DefragTrackerFree(void *arg)
 
     SCMutexDestroy(&tracker->lock);
     DefragTrackerFreeFrags(tracker);
-    SCFree(tracker);
 }
 
 /**
@@ -437,7 +421,8 @@ DefragContextNew(void)
         tracker_pool_size = DEFAULT_DEFRAG_HASH_SIZE;
     }
     dc->tracker_pool = PoolInit(tracker_pool_size, tracker_pool_size,
-        DefragTrackerNew, dc, DefragTrackerFree);
+        sizeof(DefragTracker),
+        NULL, DefragTrackerInit, dc, DefragTrackerFree);
     if (dc->tracker_pool == NULL) {
         SCLogError(SC_ERR_MEM_ALLOC,
             "Defrag: Failed to initialize tracker pool.");
@@ -456,7 +441,8 @@ DefragContextNew(void)
     }
     intmax_t frag_pool_prealloc = frag_pool_size / 2;
     dc->frag_pool = PoolInit(frag_pool_size, frag_pool_prealloc,
-        DefragFragNew, dc, DefragFragFree);
+        sizeof(Frag),
+        NULL, DefragFragInit, dc, NULL);
     if (dc->frag_pool == NULL) {
         SCLogError(SC_ERR_MEM_ALLOC,
             "Defrag: Failed to initialize fragment pool.");
index cebea4a6a69c94c42c25363298097b1a4a4199ed..cba515437121205f9d28ee025bbc232c730ea2e9 100644 (file)
@@ -153,16 +153,24 @@ int StreamTcpReassembleCheckMemcap(uint32_t size) {
 }
 
 /** \brief alloc a tcp segment pool entry */
-void *TcpSegmentPoolAlloc(void *payload_len) {
-    if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(TcpSegment) +
-                                            *((uint16_t *) payload_len)) == 0)
+void *TcpSegmentPoolAlloc()
+{
+    if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(TcpSegment)) == 0)
     {
         return NULL;
     }
 
-    TcpSegment *seg = SCMalloc(sizeof (TcpSegment));
+    TcpSegment *seg = NULL;
+
+    seg = SCMalloc(sizeof (TcpSegment));
     if (seg == NULL)
         return NULL;
+    return seg;
+}
+
+int TcpSegmentPoolInit(void *data, void *payload_len)
+{
+    TcpSegment *seg = (TcpSegment *) data;
 
     memset(seg, 0, sizeof (TcpSegment));
 
@@ -172,7 +180,7 @@ void *TcpSegmentPoolAlloc(void *payload_len) {
     seg->payload = SCMalloc(seg->payload_len);
     if (seg->payload == NULL) {
         SCFree(seg);
-        return NULL;
+        return 0;
     }
 
 #ifdef DEBUG
@@ -184,7 +192,7 @@ void *TcpSegmentPoolAlloc(void *payload_len) {
 #endif
 
     StreamTcpReassembleIncrMemuse((uint32_t)seg->pool_size + sizeof(TcpSegment));
-    return seg;
+    return 1;
 }
 
 /** \brief free a tcp segment pool entry */
@@ -205,7 +213,6 @@ void TcpSegmentPoolFree(void *ptr) {
 #endif
 
     SCFree(seg->payload);
-    SCFree(seg);
     return;
 }
 
@@ -276,8 +283,9 @@ int StreamTcpReassembleInit(char quiet)
         SCMutexLock(&segment_pool_mutex[u16]);
         segment_pool[u16] = PoolInit(segment_pool_poolsizes[u16],
                                      segment_pool_poolsizes_prealloc[u16],
-                                     TcpSegmentPoolAlloc, (void *) &
-                                     segment_pool_pktsizes[u16],
+                                     sizeof (TcpSegment),
+                                     TcpSegmentPoolAlloc, TcpSegmentPoolInit,
+                                     (void *) &segment_pool_pktsizes[u16],
                                      TcpSegmentPoolFree);
         SCMutexUnlock(&segment_pool_mutex[u16]);
     }
index 5e4c010a11b48072d51414e0d3538654fdf742c2..c2aa295d2c34b27c80699891f42e434909ec3bb0 100644 (file)
@@ -244,23 +244,28 @@ void StreamTcpSessionPktFree (Packet *p)
 }
 
 /** \brief Stream alloc function for the Pool
- *  \param null NULL ptr (value of null is ignored)
  *  \retval ptr void ptr to TcpSession structure with all vars set to 0/NULL
  */
-void *StreamTcpSessionPoolAlloc(void *null)
+void *StreamTcpSessionPoolAlloc()
 {
+    void *ptr = NULL;
+
     if (StreamTcpCheckMemcap((uint32_t)sizeof(TcpSession)) == 0)
         return NULL;
 
-    void *ptr = SCMalloc(sizeof(TcpSession));
+    ptr = SCMalloc(sizeof(TcpSession));
     if (ptr == NULL)
         return NULL;
 
-    memset(ptr, 0, sizeof(TcpSession));
+    return ptr;
+}
 
+int StreamTcpSessionPoolInit(void *data, void* initdata)
+{
+    memset(data, 0, sizeof(TcpSession));
     StreamTcpIncrMemuse((uint64_t)sizeof(TcpSession));
 
-    return ptr;
+    return 1;
 }
 
 /** \brief Pool free function
@@ -302,10 +307,7 @@ void StreamTcpSessionPoolFree(void *s)
     }
     ssn->toclient_smsg_head = NULL;
 
-    SCFree(ssn);
-
     StreamTcpDecrMemuse((uint64_t)sizeof(TcpSession));
-
 }
 
 /** \brief          To initialize the stream global configuration data
@@ -488,7 +490,9 @@ void StreamTcpInitConfig(char quiet)
     SCMutexLock(&ssn_pool_mutex);
     ssn_pool = PoolInit(stream_config.max_sessions,
                         stream_config.prealloc_sessions,
-                        StreamTcpSessionPoolAlloc, NULL,
+                        sizeof(TcpSession),
+                        StreamTcpSessionPoolAlloc,
+                        StreamTcpSessionPoolInit, NULL,
                         StreamTcpSessionPoolFree);
     if (ssn_pool == NULL) {
         SCLogError(SC_ERR_POOL_INIT, "ssn_pool is not initialized");
@@ -7513,7 +7517,7 @@ static int StreamTcpTest28(void)
     }
 
     if (StreamTcpCheckMemcap((memuse + stream_config.memcap)) != 0) {
-        printf("failed in validating the memcap");
+        printf("failed in validating the overflowed memcap");
         goto end;
     }
 
index bda9ad3c4fe2811c011d90af31251a19948a1827..2781111d4cf72c4cb26fb2e141555565c1ee7668 100644 (file)
@@ -44,12 +44,9 @@ static uint16_t toclient_min_chunk_len = 2560;
 static Pool *stream_msg_pool = NULL;
 static SCMutex stream_msg_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-void *StreamMsgAlloc(void *null) {
-    StreamMsg *s = SCMalloc(sizeof(StreamMsg));
-    if (s == NULL)
-        return NULL;
-
-    memset(s, 0, sizeof(StreamMsg));
+int StreamMsgInit(void *data, void *initdata)
+{
+    memset(data, 0, sizeof(StreamMsg));
 
 #ifdef DEBUG
     SCMutexLock(&stream_pool_memuse_mutex);
@@ -57,16 +54,7 @@ void *StreamMsgAlloc(void *null) {
     stream_pool_memcnt ++;
     SCMutexUnlock(&stream_pool_memuse_mutex);
 #endif
-    return s;
-}
-
-void StreamMsgFree(void *ptr) {
-    if (ptr == NULL)
-        return;
-
-    StreamMsg *s = (StreamMsg *)ptr;
-    SCFree(s);
-    return;
+    return 1;
 }
 
 static void StreamMsgEnqueue (StreamMsgQueue *q, StreamMsg *s) {
@@ -159,7 +147,7 @@ void StreamMsgQueuesInit(void) {
     SCMutexInit(&stream_pool_memuse_mutex, NULL);
 #endif
     SCMutexLock(&stream_msg_pool_mutex);
-    stream_msg_pool = PoolInit(0,250,StreamMsgAlloc,NULL,StreamMsgFree);
+    stream_msg_pool = PoolInit(0,250,sizeof(StreamMsg),NULL,StreamMsgInit,NULL,NULL);
     if (stream_msg_pool == NULL)
         exit(EXIT_FAILURE); /* XXX */
     SCMutexUnlock(&stream_msg_pool_mutex);
index 68529b7ba44b5ba5c7bca246c8efcfe59ebcea55..270842643938e1e8aecece0a73ee0d68ce38b069 100644 (file)
 #include "util-unittest.h"
 #include "util-debug.h"
 
-Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), void *AllocData, void (*Free)(void *))
+static int PoolMemset(void *pitem, void *initdata)
 {
-    Pool *p = NULL;
+    Pool *p = (Pool *) initdata;
 
-    if (Alloc == NULL) {
-        //printf("ERROR: PoolInit no Hash function\n");
-        goto error;
+    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
+ *
+ * \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 Free a free function or NULL if no special treatment is needed
+ * \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 (*Free)(void *))
+{
+    Pool *p = NULL;
 
     if (size != 0 && prealloc_size > size)
         goto error;
@@ -48,9 +74,17 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
     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->AllocData = AllocData;
-    p->Free  = Free;
+    p->Init = Init;
+    p->InitData = InitData;
+    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;
@@ -70,6 +104,10 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
         }
     }
 
+    p->data_buffer = SCCalloc(prealloc_size, elt_size);
+    /* FIXME better goto */
+    if (p->data_buffer == NULL)
+        goto error;
     /* prealloc the buckets and requeue them to the alloc list */
     for (u32 = 0; u32 < prealloc_size; u32++) {
         if (size == 0) { /* unlimited */
@@ -79,7 +117,15 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
 
             memset(pb, 0, sizeof(PoolBucket));
 
-            pb->data = p->Alloc(p->AllocData);
+            if (p->Alloc) {
+                pb->data = p->Alloc();
+            } else {
+                pb->data = SCMalloc(p->elt_size);
+            }
+            if (pb->data == NULL)
+                goto error;
+            if (p->Init(pb->data, p->InitData) != 1)
+                goto error;
             p->allocated++;
 
             pb->next = p->alloc_list;
@@ -93,7 +139,9 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
             p->empty_list = pb->next;
             p->empty_list_size--;
 
-            pb->data = p->Alloc(p->AllocData);
+            pb->data = (char *)p->data_buffer + u32 * elt_size;
+            if (p->Init(pb->data, p->InitData) != 1)
+                goto error;
             p->allocated++;
 
             pb->next = p->alloc_list;
@@ -111,6 +159,7 @@ error:
     return NULL;
 }
 
+
 void PoolFree(Pool *p) {
     if (p == NULL)
         return;
@@ -118,7 +167,11 @@ void PoolFree(Pool *p) {
     while (p->alloc_list != NULL) {
         PoolBucket *pb = p->alloc_list;
         p->alloc_list = pb->next;
-        p->Free(pb->data);
+        if (p->Free)
+            p->Free(pb->data);
+        if (PoolDataPreAllocated(p, pb->data) == 0) {
+            SCFree(pb->data);
+        }
         pb->data = NULL;
         if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
             SCFree(pb);
@@ -129,7 +182,11 @@ void PoolFree(Pool *p) {
         PoolBucket *pb = p->empty_list;
         p->empty_list = pb->next;
         if (pb->data!= NULL) {
-            p->Free(pb->data);
+            if (p->Free)
+                p->Free(pb->data);
+            if (PoolDataPreAllocated(p, pb->data) == 0) {
+                SCFree(pb->data);
+            }
             pb->data = NULL;
         }
         if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
@@ -139,6 +196,8 @@ void PoolFree(Pool *p) {
 
     if (p->pb_buffer)
         SCFree(p->pb_buffer);
+    if (p->data_buffer)
+        SCFree(p->data_buffer);
     SCFree(p);
 }
 
@@ -163,6 +222,7 @@ void *PoolGet(Pool *p) {
         p->empty_list_size++;
     } else {
         if (p->max_buckets == 0 || p->allocated < p->max_buckets) {
+            void *pitem;
             SCLogDebug("max_buckets %"PRIu32"", p->max_buckets);
             p->allocated++;
 
@@ -170,7 +230,16 @@ void *PoolGet(Pool *p) {
             if (p->outstanding > p->max_outstanding)
                 p->max_outstanding = p->outstanding;
 
-            SCReturnPtr(p->Alloc(p->AllocData), "void");
+            if (p->Alloc != NULL) {
+                pitem = p->Alloc();
+            } else {
+                pitem = SCMalloc(p->elt_size);
+            }
+            if (pitem != NULL) {
+                if (p->Init(pitem, p->InitData) != 1)
+                    SCReturnPtr(NULL, "void");
+            }
+            SCReturnPtr(pitem, "void");
         } else {
             SCReturnPtr(NULL, "void");
         }
@@ -194,8 +263,11 @@ void PoolReturn(Pool *p, void *data) {
     if (pb == NULL) {
         p->allocated--;
         p->outstanding--;
-        if (p->Free != NULL)
+        if (p->Free != NULL) {
             p->Free(data);
+        }
+        if (PoolDataPreAllocated(p, data) == 0)
+            SCFree(data);
 
         SCLogDebug("tried to return data %p to the pool %p, but no more "
                    "buckets available. Just freeing the data.", data, p);
@@ -224,25 +296,25 @@ void PoolPrintSaturation(Pool *p) {
  * ONLY TESTS BELOW THIS COMMENT
  */
 
-void *PoolTestAlloc(void *allocdata) {
+void *PoolTestAlloc() {
     void *ptr = SCMalloc(10);
     return ptr;
 }
-void *PoolTestAllocArg(void *allocdata) {
+int PoolTestInitArg(void *data, void *allocdata) {
     size_t len = strlen((char *)allocdata) + 1;
-    char *str = SCMalloc(len);
+    char *str = data;
     if (str != NULL)
         strlcpy(str,(char *)allocdata,len);
-    return (void *)str;
+    return 1;
 }
 
 void PoolTestFree(void *ptr) {
-    SCFree(ptr);
+    return;
 }
 
 #ifdef UNITTESTS
 static int PoolTestInit01 (void) {
-    Pool *p = PoolInit(10,5,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree);
     if (p == NULL)
         return 0;
 
@@ -253,7 +325,7 @@ static int PoolTestInit01 (void) {
 static int PoolTestInit02 (void) {
     int retval = 0;
 
-    Pool *p = PoolInit(10,5,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -289,7 +361,7 @@ static int PoolTestInit03 (void) {
     int retval = 0;
     void *data = NULL;
 
-    Pool *p = PoolInit(10,5,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -314,8 +386,6 @@ static int PoolTestInit03 (void) {
 
     retval = 1;
 end:
-    if (data != NULL)
-        SCFree(data);
     if (p != NULL)
         PoolFree(p);
     return retval;
@@ -325,7 +395,7 @@ static int PoolTestInit04 (void) {
     int retval = 0;
     char *str = NULL;
 
-    Pool *p = PoolInit(10,5,PoolTestAllocArg,(void *)"test",PoolTestFree);
+    Pool *p = PoolInit(10,5,strlen("test") + 1,NULL, PoolTestInitArg,(void *)"test",PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -356,8 +426,6 @@ static int PoolTestInit04 (void) {
 
     retval = 1;
 end:
-    if (str != NULL)
-        SCFree(str);
     if (p != NULL)
         PoolFree(p);
     return retval;
@@ -367,7 +435,7 @@ static int PoolTestInit05 (void) {
     int retval = 0;
     void *data = NULL;
 
-    Pool *p = PoolInit(10,5,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL, NULL,PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -407,8 +475,6 @@ static int PoolTestInit05 (void) {
 
     retval = 1;
 end:
-    if (data != NULL)
-        SCFree(data);
     if (p != NULL)
         PoolFree(p);
     return retval;
@@ -419,7 +485,7 @@ static int PoolTestInit06 (void) {
     void *data = NULL;
     void *data2 = NULL;
 
-    Pool *p = PoolInit(1,0,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(1,0,10,PoolTestAlloc,NULL,NULL,PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -466,10 +532,6 @@ static int PoolTestInit06 (void) {
 
     retval = 1;
 end:
-    if (data != NULL)
-        SCFree(data);
-    if (data2 != NULL)
-        SCFree(data2);
     if (p != NULL)
         PoolFree(p);
     return retval;
@@ -481,7 +543,7 @@ static int PoolTestInit07 (void) {
     void *data = NULL;
     void *data2 = NULL;
 
-    Pool *p = PoolInit(0,1,PoolTestAlloc,NULL,PoolTestFree);
+    Pool *p = PoolInit(0,1,10,PoolTestAlloc,NULL,NULL,PoolTestFree);
     if (p == NULL)
         goto end;
 
@@ -549,10 +611,6 @@ static int PoolTestInit07 (void) {
 
     retval = 1;
 end:
-    if (data != NULL)
-        SCFree(data);
-    if (data2 != NULL)
-        SCFree(data2);
     if (p != NULL)
         PoolFree(p);
     return retval;
index 67c6b0663c1d7e1b2696d9835935f31ce5242fb8..3e8ae2e6c80a01a43a951056941d92c4aa45dac0 100644 (file)
@@ -36,6 +36,7 @@ typedef struct PoolBucket_ {
 /* pool structure */
 typedef struct Pool_ {
     uint32_t max_buckets;
+    uint32_t preallocated;
     uint32_t allocated;
 
     PoolBucket *alloc_list;
@@ -46,17 +47,20 @@ typedef struct Pool_ {
 
     PoolBucket *pb_buffer;
     void *data_buffer;
+    int data_buffer_size;
 
-    void *(*Alloc)(void *);
-    void *AllocData;
+    void *(*Alloc)();
+    int (*Init)(void *, void *);
+    void *InitData;
     void (*Free)(void *);
 
+    uint32_t elt_size;
     uint32_t outstanding;
     uint32_t max_outstanding;
 } Pool;
 
 /* prototypes */
-Pool* PoolInit(uint32_t, uint32_t, void *(*Alloc)(void *), void *, void (*Free)(void *));
+Pool* PoolInit(uint32_t, uint32_t, uint32_t, void *(*Alloc)(), int (*Init)(void *, void *), void *, void (*Free)(void *));
 void PoolFree(Pool *);
 void PoolPrint(Pool *);
 void PoolPrintSaturation(Pool *p);