2007-05-12 15:51:02 +02:00
/*
* Contribution from Aleksandar Lazic < al - haproxy @ none . at >
*
2007-05-12 16:14:55 +02:00
* Build with :
* gcc - O2 - o test_pools test_pools . c
* or with dlmalloc too :
* gcc - O2 - o test_pools - D USE_DLMALLOC test_pools . c - DUSE_DL_PREFIX dlmalloc . c
2007-05-12 15:51:02 +02:00
*/
# include <sys/time.h>
# include <time.h>
# include <stdlib.h>
# include <stdbool.h>
# include <string.h>
# include <stdio.h>
static struct timeval timeval_current ( void )
{
struct timeval tv ;
gettimeofday ( & tv , NULL ) ;
return tv ;
}
static double timeval_elapsed ( struct timeval * tv )
{
struct timeval tv2 = timeval_current ( ) ;
return ( tv2 . tv_sec - tv - > tv_sec ) +
( tv2 . tv_usec - tv - > tv_usec ) * 1.0e-6 ;
}
# define torture_assert(test, expr, str) if (!(expr)) { \
printf ( " failure: %s [ \n %s: Expression %s failed: %s \n ] \n " , \
test , __location__ , # expr , str ) ; \
return false ; \
}
# define torture_assert_str_equal(test, arg1, arg2, desc) \
if ( strcmp ( arg1 , arg2 ) ) { \
printf ( " failure: %s [ \n %s: Expected %s, got %s: %s \n ] \n " , \
test , __location__ , arg1 , arg2 , desc ) ; \
return false ; \
}
/* added pools from haproxy */
# include <stdlib.h>
/*
* Returns a pointer to an area of < __len > bytes taken from the pool < pool > or
* dynamically allocated . In the first case , < __pool > is updated to point to
* the next element in the list .
*/
# define pool_alloc_from(__pool, __len) \
( { \
void * __p ; \
if ( ( __p = ( __pool ) ) = = NULL ) \
__p = malloc ( ( ( __len ) > = sizeof ( void * ) ) ? \
( __len ) : sizeof ( void * ) ) ; \
else { \
__pool = * ( void * * ) ( __pool ) ; \
} \
__p ; \
} )
/*
* Puts a memory area back to the corresponding pool .
* Items are chained directly through a pointer that
* is written in the beginning of the memory area , so
* there ' s no need for any carrier cell . This implies
* that each memory area is at least as big as one
* pointer .
*/
# define pool_free_to(__pool, __ptr) \
( { \
* ( void * * ) ( __ptr ) = ( void * ) ( __pool ) ; \
__pool = ( void * ) ( __ptr ) ; \
} )
/*
* Returns a pointer to type < type > taken from the
* pool < pool_type > or dynamically allocated . In the
* first case , < pool_type > is updated to point to the
* next element in the list .
*/
# define pool_alloc(type) \
( { \
void * __p ; \
if ( ( __p = pool_ # # type ) = = NULL ) \
__p = malloc ( sizeof_ # # type ) ; \
else { \
pool_ # # type = * ( void * * ) pool_ # # type ; \
} \
__p ; \
} )
/*
* Puts a memory area back to the corresponding pool .
* Items are chained directly through a pointer that
* is written in the beginning of the memory area , so
* there ' s no need for any carrier cell . This implies
* that each memory area is at least as big as one
* pointer .
*/
# define pool_free(type, ptr) \
( { \
* ( void * * ) ptr = ( void * ) pool_ # # type ; \
pool_ # # type = ( void * ) ptr ; \
} )
/*
* This function destroys a pull by freeing it completely .
* This should be called only under extreme circumstances .
*/
static inline void pool_destroy ( void * * pool )
{
void * temp , * next ;
next = pool ;
while ( next ) {
temp = next ;
next = * ( void * * ) temp ;
free ( temp ) ;
}
}
# define sizeof_talloc 1000
/*
measure the speed of hapx versus malloc
*/
static bool test_speed1 ( void )
{
void * * pool_talloc = NULL ;
void * ctx = pool_alloc ( talloc ) ;
unsigned count ;
const int loop = 1000 ;
int i ;
struct timeval tv ;
printf ( " test: speed [ \n haproxy-pool VS MALLOC SPEED 2 \n ] \n " ) ;
tv = timeval_current ( ) ;
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
for ( i = 0 ; i < loop ; i + + ) {
p1 = pool_alloc_from ( pool_talloc , 10 + loop % 100 ) ;
p2 = pool_alloc_from ( pool_talloc , strlen ( " foo bar " ) + 1 ) ;
strcpy ( p2 , " foo bar " ) ;
p3 = pool_alloc_from ( pool_talloc , 300 ) ;
pool_free_to ( pool_talloc , p1 ) ;
pool_free_to ( pool_talloc , p3 ) ;
pool_free_to ( pool_talloc , p2 ) ;
}
count + = 3 * loop ;
} while ( timeval_elapsed ( & tv ) < 5.0 ) ;
2007-05-12 16:14:55 +02:00
fprintf ( stderr , " haproxy : %10.0f ops/sec \n " , count / timeval_elapsed ( & tv ) ) ;
2007-05-12 15:51:02 +02:00
pool_destroy ( pool_talloc ) ;
tv = timeval_current ( ) ;
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
for ( i = 0 ; i < loop ; i + + ) {
p1 = malloc ( 10 + loop % 100 ) ;
2007-05-12 16:14:55 +02:00
p2 = malloc ( strlen ( " foo bar " ) + 1 ) ;
strcpy ( p2 , " foo bar " ) ;
2007-05-12 15:51:02 +02:00
p3 = malloc ( 300 ) ;
free ( p1 ) ;
free ( p2 ) ;
free ( p3 ) ;
}
count + = 3 * loop ;
} while ( timeval_elapsed ( & tv ) < 5.0 ) ;
2007-05-12 16:14:55 +02:00
fprintf ( stderr , " malloc : %10.0f ops/sec \n " , count / timeval_elapsed ( & tv ) ) ;
# ifdef USE_DLMALLOC
tv = timeval_current ( ) ;
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
for ( i = 0 ; i < loop ; i + + ) {
p1 = dlmalloc ( 10 + loop % 100 ) ;
p2 = dlmalloc ( strlen ( " foo bar " ) + 1 ) ;
strcpy ( p2 , " foo bar " ) ;
p3 = dlmalloc ( 300 ) ;
dlfree ( p1 ) ;
dlfree ( p2 ) ;
dlfree ( p3 ) ;
}
count + = 3 * loop ;
} while ( timeval_elapsed ( & tv ) < 5.0 ) ;
fprintf ( stderr , " dlmalloc: %10.0f ops/sec \n " , count / timeval_elapsed ( & tv ) ) ;
# endif
2007-05-12 15:51:02 +02:00
printf ( " success: speed1 \n " ) ;
return true ;
}
int main ( void )
{
bool ret = test_speed1 ( ) ;
if ( ! ret )
return - 1 ;
return 0 ;
}