@ -28,14 +28,40 @@
# 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 , PoolTestAlloc Arg, ( void * ) " test " , PoolTestFree ) ;
Pool * p = PoolInit ( 10 , 5 , strlen ( " test " ) + 1 , NULL , PoolTestInit Arg, ( 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 ;