suricata
util-pool.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \defgroup utilpool Pool
20  *
21  * ::Pool are an effective way to maintain a set of ready to use
22  * structures.
23  *
24  * To create a ::Pool, you need to use PoolInit(). You can
25  * get an item from the ::Pool by using PoolGet(). When you're
26  * done with it call PoolReturn().
27  * To destroy the ::Pool, call PoolFree(), it will free all used
28  * memory.
29  *
30  * @{
31  */
32 
33 /**
34  * \file
35  *
36  * \author Victor Julien <victor@inliniac.net>
37  *
38  * Pool utility functions
39  */
40 
41 #include "suricata-common.h"
42 #include "util-pool.h"
43 #include "util-pool-thread.h"
44 #include "util-unittest.h"
45 #include "util-debug.h"
46 
47 static int PoolMemset(void *pitem, void *initdata)
48 {
49  Pool *p = (Pool *) initdata;
50 
51  memset(pitem, 0, p->elt_size);
52  return 1;
53 }
54 
55 /**
56  * \brief Check if data is preallocated
57  * \retval false if not inside the prealloc'd block, true if inside */
58 static bool PoolDataPreAllocated(Pool *p, void *data)
59 {
60  ptrdiff_t delta = data - p->data_buffer;
61  if ((delta < 0) || (delta > p->data_buffer_size)) {
62  return false;
63  }
64  return true;
65 }
66 
67 /** \brief Init a Pool
68  *
69  * PoolInit() creates a ::Pool. The Alloc function must only do
70  * allocation stuff. The Cleanup function must not try to free
71  * the PoolBucket::data. This is done by the ::Pool management
72  * system.
73  *
74  * \param size
75  * \param prealloc_size
76  * \param elt_size Memory size of an element
77  * \param Alloc An allocation function or NULL to use a standard SCMalloc
78  * \param Init An init function or NULL to use a standard memset to 0
79  * \param InitData Init data
80  * \param Cleanup a free function or NULL if no special treatment is needed
81  * \param Free free func
82  * \retval the allocated Pool
83  */
84 Pool *PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size,
85  void *(*Alloc)(void), int (*Init)(void *, void *), void *InitData,
86  void (*Cleanup)(void *), void (*Free)(void *))
87 {
88  sc_errno = SC_OK;
89 
90  Pool *p = NULL;
91 
92  if (size != 0 && prealloc_size > size) {
94  goto error;
95  }
96  if (size != 0 && elt_size == 0) {
98  goto error;
99  }
100  if (elt_size && Free) {
102  goto error;
103  }
104  if (elt_size == 0 && Alloc == NULL) {
106  goto error;
107  }
108 
109  /* setup the filter */
110  p = SCCalloc(1, sizeof(Pool));
111  if (unlikely(p == NULL)) {
113  goto error;
114  }
115 
116  p->max_buckets = size;
117  p->preallocated = prealloc_size;
118  p->elt_size = elt_size;
119  p->data_buffer_size = prealloc_size * elt_size;
120  p->Alloc = Alloc;
121  p->Init = Init;
122  p->InitData = InitData;
123  p->Cleanup = Cleanup;
124  p->Free = Free;
125  if (p->Init == NULL) {
126  p->Init = PoolMemset;
127  p->InitData = p;
128  }
129 
130  /* alloc the buckets and place them in the empty list */
131  uint32_t u32 = 0;
132  if (size > 0) {
133  PoolBucket *pb = SCCalloc(size, sizeof(PoolBucket));
134  if (unlikely(pb == NULL)) {
136  goto error;
137  }
138  memset(pb, 0, size * sizeof(PoolBucket));
139  p->pb_buffer = pb;
140  for (u32 = 0; u32 < size; u32++) {
141  /* populate pool */
142  pb->next = p->empty_stack;
144  p->empty_stack = pb;
145  p->empty_stack_size++;
146  pb++;
147  }
148 
149  p->data_buffer = SCCalloc(prealloc_size, elt_size);
150  /* FIXME better goto */
151  if (p->data_buffer == NULL) {
153  goto error;
154  }
155  }
156  /* prealloc the buckets and requeue them to the alloc list */
157  for (u32 = 0; u32 < prealloc_size; u32++) {
158  if (size == 0) { /* unlimited */
159  PoolBucket *pb = SCCalloc(1, sizeof(PoolBucket));
160  if (unlikely(pb == NULL)) {
162  goto error;
163  }
164 
165  if (p->Alloc) {
166  pb->data = p->Alloc();
167  } else {
168  pb->data = SCMalloc(p->elt_size);
169  }
170  if (pb->data == NULL) {
171  SCFree(pb);
173  goto error;
174  }
175  if (p->Init(pb->data, p->InitData) != 1) {
176  if (p->Free)
177  p->Free(pb->data);
178  else
179  SCFree(pb->data);
180  SCFree(pb);
182  goto error;
183  }
184  p->allocated++;
185 
186  pb->next = p->alloc_stack;
187  p->alloc_stack = pb;
188  p->alloc_stack_size++;
189  } else {
190  PoolBucket *pb = p->empty_stack;
191  if (pb == NULL) {
193  goto error;
194  }
195 
196  pb->data = (char *)p->data_buffer + u32 * elt_size;
197  if (p->Init(pb->data, p->InitData) != 1) {
198  pb->data = NULL;
200  goto error;
201  }
202 
203  p->empty_stack = pb->next;
204  p->empty_stack_size--;
205 
206  p->allocated++;
207 
208  pb->next = p->alloc_stack;
209  p->alloc_stack = pb;
210  p->alloc_stack_size++;
211  }
212  }
213 
214  return p;
215 
216 error:
217  if (p != NULL) {
218  PoolFree(p);
219  }
220  return NULL;
221 }
222 
223 void PoolFree(Pool *p)
224 {
225  if (p == NULL)
226  return;
227 
228  while (p->alloc_stack != NULL) {
229  PoolBucket *pb = p->alloc_stack;
230  p->alloc_stack = pb->next;
231  if (p->Cleanup)
232  p->Cleanup(pb->data);
233  if (!PoolDataPreAllocated(p, pb->data)) {
234  if (p->Free)
235  p->Free(pb->data);
236  else
237  SCFree(pb->data);
238  }
239  pb->data = NULL;
240  if (!(pb->flags & POOL_BUCKET_PREALLOCATED)) {
241  SCFree(pb);
242  }
243  }
244 
245  while (p->empty_stack != NULL) {
246  PoolBucket *pb = p->empty_stack;
247  p->empty_stack = pb->next;
248  if (pb->data!= NULL) {
249  if (p->Cleanup)
250  p->Cleanup(pb->data);
251  if (!PoolDataPreAllocated(p, pb->data)) {
252  if (p->Free)
253  p->Free(pb->data);
254  else
255  SCFree(pb->data);
256  }
257  pb->data = NULL;
258  }
259  if (!(pb->flags & POOL_BUCKET_PREALLOCATED)) {
260  SCFree(pb);
261  }
262  }
263 
264  if (p->pb_buffer)
265  SCFree(p->pb_buffer);
266  if (p->data_buffer)
267  SCFree(p->data_buffer);
268  SCFree(p);
269 }
270 
271 void PoolPrint(Pool *p)
272 {
273  printf("\n----------- Hash Table Stats ------------\n");
274  printf("Buckets: %" PRIu32 "\n", p->empty_stack_size + p->alloc_stack_size);
275  printf("-----------------------------------------\n");
276 }
277 
278 void *PoolGet(Pool *p)
279 {
280  SCEnter();
281 
282  PoolBucket *pb = p->alloc_stack;
283  if (pb != NULL) {
284  /* pull from the alloc list */
285  p->alloc_stack = pb->next;
286  p->alloc_stack_size--;
287 
288  /* put in the empty list */
289  pb->next = p->empty_stack;
290  p->empty_stack = pb;
291  p->empty_stack_size++;
292  } else {
293  if (p->max_buckets == 0 || p->allocated < p->max_buckets) {
294  void *pitem;
295  SCLogDebug("max_buckets %"PRIu32"", p->max_buckets);
296 
297  if (p->Alloc != NULL) {
298  pitem = p->Alloc();
299  } else {
300  pitem = SCMalloc(p->elt_size);
301  }
302 
303  if (pitem != NULL) {
304  if (p->Init(pitem, p->InitData) != 1) {
305  if (p->Free != NULL)
306  p->Free(pitem);
307  else
308  SCFree(pitem);
309  SCReturnPtr(NULL, "void");
310  }
311 
312  p->allocated++;
313  p->outstanding++;
314 #ifdef DEBUG
315  if (p->outstanding > p->max_outstanding)
316  p->max_outstanding = p->outstanding;
317 #endif
318  }
319 
320  SCReturnPtr(pitem, "void");
321  } else {
322  SCReturnPtr(NULL, "void");
323  }
324  }
325 
326  void *ptr = pb->data;
327  pb->data = NULL;
328  p->outstanding++;
329 #ifdef DEBUG
330  if (p->outstanding > p->max_outstanding)
331  p->max_outstanding = p->outstanding;
332 #endif
333  SCReturnPtr(ptr,"void");
334 }
335 
336 void PoolReturn(Pool *p, void *data)
337 {
338  SCEnter();
339 
340  PoolBucket *pb = p->empty_stack;
341 
342  SCLogDebug("pb %p", pb);
343 
344  if (pb == NULL) {
345  p->allocated--;
346  p->outstanding--;
347  if (p->Cleanup != NULL) {
348  p->Cleanup(data);
349  }
350  if (!PoolDataPreAllocated(p, data)) {
351  if (p->Free)
352  p->Free(data);
353  else
354  SCFree(data);
355  }
356 
357  SCLogDebug("tried to return data %p to the pool %p, but no more "
358  "buckets available. Just freeing the data.", data, p);
359  SCReturn;
360  }
361 
362  /* pull from the alloc list */
363  p->empty_stack = pb->next;
364  p->empty_stack_size--;
365 
366  /* put in the alloc list */
367  pb->next = p->alloc_stack;
368  p->alloc_stack = pb;
369  p->alloc_stack_size++;
370 
371  pb->data = data;
372  p->outstanding--;
373  SCReturn;
374 }
375 
377 {
378  if (p->max_buckets > 0) {
379  SCLogDebug("pool %p is using %" PRIu32 " out of %" PRIu32 " items (%02.1f%%), max %" PRIu32
380  " (%02.1f%%): pool struct memory %" PRIu64 ".",
381  p, p->outstanding, p->max_buckets,
382  (float)(p->outstanding) / (float)(p->max_buckets) * 100, p->max_outstanding,
383  (float)(p->max_outstanding) / (float)(p->max_buckets) * 100,
384  (uint64_t)(p->max_buckets * sizeof(PoolBucket)));
385  }
386 }
387 
388 /*
389  * ONLY TESTS BELOW THIS COMMENT
390  */
391 
392 #ifdef UNITTESTS
393 static void *PoolTestAlloc(void)
394 {
395  void *ptr = SCMalloc(10);
396  if (unlikely(ptr == NULL))
397  return NULL;
398  return ptr;
399 }
400 static int PoolTestInitArg(void *data, void *allocdata)
401 {
402  size_t len = strlen((char *)allocdata) + 1;
403  char *str = data;
404  if (str != NULL)
405  strlcpy(str,(char *)allocdata,len);
406  return 1;
407 }
408 
409 static void PoolTestFree(void *ptr)
410 {
411  return;
412 }
413 
414 static int PoolTestInit01 (void)
415 {
416  Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
417  if (p == NULL)
418  return 0;
419 
420  PoolFree(p);
421  return 1;
422 }
423 
424 static int PoolTestInit02 (void)
425 {
426  int retval = 0;
427 
428  Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
429  if (p == NULL)
430  goto end;
431 
432  if (p->alloc_stack == NULL || p->empty_stack == NULL) {
433  printf("list(s) not properly initialized (a:%p e:%p): ",
434  p->alloc_stack, p->empty_stack);
435  retval = 0;
436  goto end;
437  }
438 
439  if (p->Alloc != PoolTestAlloc) {
440  printf("Alloc func ptr %p != %p: ",
441  p->Alloc, PoolTestAlloc);
442  retval = 0;
443  goto end;
444  }
445 
446  if (p->Cleanup != PoolTestFree) {
447  printf("Free func ptr %p != %p: ",
448  p->Cleanup, PoolTestFree);
449  retval = 0;
450  goto end;
451  }
452 
453  retval = 1;
454 end:
455  if (p != NULL)
456  PoolFree(p);
457  return retval;
458 }
459 
460 static int PoolTestInit03 (void)
461 {
462  int retval = 0;
463  void *data = NULL;
464 
465  Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
466  if (p == NULL)
467  goto end;
468 
469  data = PoolGet(p);
470  if (data == NULL) {
471  printf("PoolGet returned NULL: ");
472  retval = 0;
473  goto end;
474  }
475 
476  if (p->alloc_stack_size != 4) {
477  printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
478  retval = 0;
479  goto end;
480  }
481 
482  if (p->empty_stack_size != 6) {
483  printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
484  retval = 0;
485  goto end;
486  }
487 
488  retval = 1;
489 end:
490  if (p != NULL)
491  PoolFree(p);
492  return retval;
493 }
494 
495 static int PoolTestInit04 (void)
496 {
497  int retval = 0;
498  char *str = NULL;
499 
500  Pool *p = PoolInit(10,5,strlen("test") + 1,NULL, PoolTestInitArg,(void *)"test",PoolTestFree, NULL);
501  if (p == NULL)
502  goto end;
503 
504  str = PoolGet(p);
505  if (str == NULL) {
506  printf("PoolGet returned NULL: ");
507  retval = 0;
508  goto end;
509  }
510 
511  if (strcmp(str, "test") != 0) {
512  printf("Memory not properly initialized: ");
513  retval = 0;
514  goto end;
515  }
516 
517  if (p->alloc_stack_size != 4) {
518  printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
519  retval = 0;
520  goto end;
521  }
522 
523  if (p->empty_stack_size != 6) {
524  printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
525  retval = 0;
526  goto end;
527  }
528 
529  retval = 1;
530 end:
531  if (p != NULL)
532  PoolFree(p);
533  return retval;
534 }
535 
536 static int PoolTestInit05 (void)
537 {
538  int retval = 0;
539  void *data = NULL;
540 
541  Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL, NULL,PoolTestFree, NULL);
542  if (p == NULL)
543  goto end;
544 
545  data = PoolGet(p);
546  if (data == NULL) {
547  printf("PoolGet returned NULL: ");
548  retval = 0;
549  goto end;
550  }
551 
552  if (p->alloc_stack_size != 4) {
553  printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size);
554  retval = 0;
555  goto end;
556  }
557 
558  if (p->empty_stack_size != 6) {
559  printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size);
560  retval = 0;
561  goto end;
562  }
563 
564  PoolReturn(p, data);
565  data = NULL;
566 
567  if (p->alloc_stack_size != 5) {
568  printf("p->alloc_stack_size 5 != %" PRIu32 ": ", p->alloc_stack_size);
569  retval = 0;
570  goto end;
571  }
572 
573  if (p->empty_stack_size != 5) {
574  printf("p->empty_stack_size 5 != %" PRIu32 ": ", p->empty_stack_size);
575  retval = 0;
576  goto end;
577  }
578 
579  retval = 1;
580 end:
581  if (p != NULL)
582  PoolFree(p);
583  return retval;
584 }
585 
586 static int PoolTestInit06 (void)
587 {
588  int retval = 0;
589  void *data = NULL;
590  void *data2 = NULL;
591 
592  Pool *p = PoolInit(1,0,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
593  if (p == NULL)
594  goto end;
595 
596  if (p->allocated != 0) {
597  printf("p->allocated 0 != %" PRIu32 ": ", p->allocated);
598  retval = 0;
599  goto end;
600  }
601 
602  data = PoolGet(p);
603  if (data == NULL) {
604  printf("PoolGet returned NULL: ");
605  retval = 0;
606  goto end;
607  }
608 
609  if (p->allocated != 1) {
610  printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
611  retval = 0;
612  goto end;
613  }
614 
615  data2 = PoolGet(p);
616  if (data2 != NULL) {
617  printf("PoolGet returned %p, expected NULL: ", data2);
618  retval = 0;
619  goto end;
620  }
621 
622  PoolReturn(p,data);
623  data = NULL;
624 
625  if (p->allocated != 1) {
626  printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
627  retval = 0;
628  goto end;
629  }
630 
631  if (p->alloc_stack_size != 1) {
632  printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size);
633  retval = 0;
634  goto end;
635  }
636 
637  retval = 1;
638 end:
639  if (p != NULL)
640  PoolFree(p);
641  return retval;
642 }
643 
644 /** \test pool with unlimited size */
645 static int PoolTestInit07 (void)
646 {
647  int retval = 0;
648  void *data = NULL;
649  void *data2 = NULL;
650 
651  Pool *p = PoolInit(0,1,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL);
652  if (p == NULL)
653  goto end;
654 
655  if (p->max_buckets != 0) {
656  printf("p->max_buckets 0 != %" PRIu32 ": ", p->max_buckets);
657  retval = 0;
658  goto end;
659  }
660 
661  if (p->allocated != 1) {
662  printf("p->allocated 1 != %" PRIu32 ": ", p->allocated);
663  retval = 0;
664  goto end;
665  }
666 
667  data = PoolGet(p);
668  if (data == NULL) {
669  printf("PoolGet returned NULL: ");
670  retval = 0;
671  goto end;
672  }
673 
674  if (p->allocated != 1) {
675  printf("(2) p->allocated 1 != %" PRIu32 ": ", p->allocated);
676  retval = 0;
677  goto end;
678  }
679 
680  data2 = PoolGet(p);
681  if (data2 == NULL) {
682  printf("PoolGet returned NULL: ");
683  retval = 0;
684  goto end;
685  }
686 
687  if (p->allocated != 2) {
688  printf("(3) p->allocated 2 != %" PRIu32 ": ", p->allocated);
689  retval = 0;
690  goto end;
691  }
692 
693  PoolReturn(p,data);
694  data = NULL;
695 
696  if (p->allocated != 2) {
697  printf("(4) p->allocated 2 != %" PRIu32 ": ", p->allocated);
698  retval = 0;
699  goto end;
700  }
701 
702  if (p->alloc_stack_size != 1) {
703  printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size);
704  retval = 0;
705  goto end;
706  }
707 
708  PoolReturn(p,data2);
709  data2 = NULL;
710 
711  if (p->allocated != 1) {
712  printf("(5) p->allocated 1 != %" PRIu32 ": ", p->allocated);
713  retval = 0;
714  goto end;
715  }
716 
717  retval = 1;
718 end:
719  if (p != NULL)
720  PoolFree(p);
721  return retval;
722 }
723 #endif /* UNITTESTS */
724 
726 {
727 #ifdef UNITTESTS
728  UtRegisterTest("PoolTestInit01", PoolTestInit01);
729  UtRegisterTest("PoolTestInit02", PoolTestInit02);
730  UtRegisterTest("PoolTestInit03", PoolTestInit03);
731  UtRegisterTest("PoolTestInit04", PoolTestInit04);
732  UtRegisterTest("PoolTestInit05", PoolTestInit05);
733  UtRegisterTest("PoolTestInit06", PoolTestInit06);
734  UtRegisterTest("PoolTestInit07", PoolTestInit07);
735 
737 #endif /* UNITTESTS */
738 }
739 
740 
741 /**
742  * @}
743  */
len
uint8_t len
Definition: app-layer-dnp3.h:2
Pool_::pb_buffer
PoolBucket * pb_buffer
Definition: util-pool.h:58
Pool_::Free
void(* Free)(void *)
Definition: util-pool.h:64
Pool_::Init
int(* Init)(void *, void *)
Definition: util-pool.h:61
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
POOL_BUCKET_PREALLOCATED
#define POOL_BUCKET_PREALLOCATED
Definition: util-pool.h:33
util-pool-thread.h
PoolRegisterTests
void PoolRegisterTests(void)
Definition: util-pool.c:725
SC_EINVAL
@ SC_EINVAL
Definition: util-error.h:30
PoolPrintSaturation
void PoolPrintSaturation(Pool *p)
Definition: util-pool.c:376
Pool_::alloc_stack
PoolBucket * alloc_stack
Definition: util-pool.h:51
Pool_
Definition: util-pool.h:43
Pool_::Cleanup
void(* Cleanup)(void *)
Definition: util-pool.h:63
util-unittest.h
SC_ENOMEM
@ SC_ENOMEM
Definition: util-error.h:29
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
util-debug.h
Pool_::empty_stack_size
uint32_t empty_stack_size
Definition: util-pool.h:54
PoolBucket_::next
struct PoolBucket_ * next
Definition: util-pool.h:39
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
Pool_::outstanding
uint32_t outstanding
Definition: util-pool.h:67
PoolBucket_::data
void * data
Definition: util-pool.h:37
SCReturn
#define SCReturn
Definition: util-debug.h:273
PoolFree
void PoolFree(Pool *p)
Definition: util-pool.c:223
SC_OK
@ SC_OK
Definition: util-error.h:27
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
PoolBucket_
Definition: util-pool.h:36
PoolReturn
void PoolReturn(Pool *p, void *data)
Definition: util-pool.c:336
Pool_::max_buckets
uint32_t max_buckets
Definition: util-pool.h:44
PoolThreadRegisterTests
void PoolThreadRegisterTests(void)
Definition: util-pool-thread.c:401
suricata-common.h
Pool_::Alloc
void *(* Alloc)(void)
Definition: util-pool.h:60
Pool_::preallocated
uint32_t preallocated
Definition: util-pool.h:45
Pool_::allocated
uint32_t allocated
Definition: util-pool.h:46
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:291
PoolGet
void * PoolGet(Pool *p)
Definition: util-pool.c:278
Pool_::data_buffer_size
int data_buffer_size
Definition: util-pool.h:56
Pool_::empty_stack
PoolBucket * empty_stack
Definition: util-pool.h:53
SCFree
#define SCFree(p)
Definition: util-mem.h:61
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
PoolBucket_::flags
uint8_t flags
Definition: util-pool.h:38
Pool_::elt_size
uint32_t elt_size
Definition: util-pool.h:66
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
util-pool.h
PoolInit
Pool * PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(void), int(*Init)(void *, void *), void *InitData, void(*Cleanup)(void *), void(*Free)(void *))
Init a Pool.
Definition: util-pool.c:84
Pool_::InitData
void * InitData
Definition: util-pool.h:62
Pool_::alloc_stack_size
uint32_t alloc_stack_size
Definition: util-pool.h:49
Pool_::data_buffer
void * data_buffer
Definition: util-pool.h:57
PoolPrint
void PoolPrint(Pool *p)
Definition: util-pool.c:271