diff --git a/tests/test_pools.c b/tests/test_pools.c new file mode 100644 index 000000000..9ef833c19 --- /dev/null +++ b/tests/test_pools.c @@ -0,0 +1,184 @@ +/* + * Contribution from Aleksandar Lazic + * + * Build with : gcc -O2 -o test_pools test_pools.c + */ + +#include +#include +#include +#include +#include +#include + +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 + +/* + * Returns a pointer to an area of <__len> bytes taken from the 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 taken from the + * pool or dynamically allocated. In the + * first case, 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 [\nhaproxy-pool VS MALLOC SPEED 2\n]\n"); + + tv = timeval_current(); + count = 0; + do { + void *p1, *p2, *p3; + for (i=0;i