/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "test.h"

#if INCLUDE_POOL_PERF_TEST

#include <pjlib.h>
#include <pj/compat/malloc.h>

#if !PJ_HAS_HIGH_RES_TIMER
# error Need high resolution timer for this test.
#endif

#define THIS_FILE   "test"

#define LOOP	    10
#define COUNT	    1024
static unsigned	    sizes[COUNT];
static char	   *p[COUNT];
#define MIN_SIZE    4
#define MAX_SIZE    512
static unsigned total_size;


static int pool_test_pool()
{
    int i;
    pj_pool_t *pool = pj_pool_create(mem, NULL, total_size + 4*COUNT, 0, NULL);
    if (!pool)
	return -1;

    for (i=0; i<COUNT; ++i) {
	char *p;
	if ( (p=(char*)pj_pool_alloc(pool, sizes[i])) == NULL) {
	    PJ_LOG(3,(THIS_FILE,"   error: pool failed to allocate %d bytes",
		      sizes[i]));
	    pj_pool_release(pool);
	    return -1;
	}
	*p = '\0';
    }

    pj_pool_release(pool);
    return 0;
}

/* Symbian doesn't have malloc()/free(), so we use new/delete instead */
//#if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0
#if 0
static int pool_test_malloc_free()
{
    int i; /* must be signed */

    for (i=0; i<COUNT; ++i) {
		p[i] = new char[sizes[i]];
		if (!p[i]) {
			PJ_LOG(3,(THIS_FILE,"   error: malloc failed to allocate %d bytes",
					  sizes[i]));
			--i;
			while (i >= 0) {
				delete [] p[i];
				--i;
			}
			return -1;
		}
		*p[i] = '\0';
    }

    for (i=0; i<COUNT; ++i) {
    	delete [] p[i];
    }

    return 0;
}

#else	/* PJ_SYMBIAN */

static int pool_test_malloc_free()
{
    int i; /* must be signed */

    for (i=0; i<COUNT; ++i) {
	p[i] = (char*)malloc(sizes[i]);
	if (!p[i]) {
	    PJ_LOG(3,(THIS_FILE,"   error: malloc failed to allocate %d bytes",
		      sizes[i]));
	    --i;
	    while (i >= 0)
		free(p[i]), --i;
	    return -1;
	}
	*p[i] = '\0';
    }

    for (i=0; i<COUNT; ++i) {
	free(p[i]);
    }

    return 0;
}

#endif /* PJ_SYMBIAN */

int pool_perf_test()
{
    unsigned i;
    pj_uint32_t pool_time=0, malloc_time=0, pool_time2=0;
    pj_timestamp start, end;
    pj_uint32_t best, worst;

    /* Initialize size of chunks to allocate in for the test. */
    for (i=0; i<COUNT; ++i) {
	unsigned aligned_size;
	sizes[i] = MIN_SIZE + (pj_rand() % MAX_SIZE);
	aligned_size = sizes[i];
	if (aligned_size & (PJ_POOL_ALIGNMENT-1))
	    aligned_size = ((aligned_size + PJ_POOL_ALIGNMENT - 1)) & ~(PJ_POOL_ALIGNMENT - 1);
	total_size += aligned_size;
    }

    /* Add some more for pool admin area */
    total_size += 512;

    PJ_LOG(3, (THIS_FILE, "Benchmarking pool.."));

    /* Warmup */
    pool_test_pool();
    pool_test_malloc_free();

    for (i=0; i<LOOP; ++i) {
	pj_get_timestamp(&start);
	if (pool_test_pool()) {
	    return 1;
	}
	pj_get_timestamp(&end);
	pool_time += (end.u32.lo - start.u32.lo);

	pj_get_timestamp(&start);
	if (pool_test_malloc_free()) {
	    return 2;
	}
	pj_get_timestamp(&end);
	malloc_time += (end.u32.lo - start.u32.lo);

	pj_get_timestamp(&start);
	if (pool_test_pool()) {
	    return 4;
	}
	pj_get_timestamp(&end);
	pool_time2 += (end.u32.lo - start.u32.lo);
    }

    PJ_LOG(4,(THIS_FILE,"..LOOP count:                        %u",LOOP));
    PJ_LOG(4,(THIS_FILE,"..number of alloc/dealloc per loop:  %u",COUNT));
    PJ_LOG(4,(THIS_FILE,"..pool allocation/deallocation time: %u",pool_time));
    PJ_LOG(4,(THIS_FILE,"..malloc/free time:                  %u",malloc_time));
    PJ_LOG(4,(THIS_FILE,"..pool again, second invocation:     %u",pool_time2));

    if (pool_time2==0) pool_time2=1;
    if (pool_time < pool_time2)
	best = pool_time, worst = pool_time2;
    else
	best = pool_time2, worst = pool_time;
    
    /* avoid division by zero */
    if (best==0) best=1;
    if (worst==0) worst=1;

    PJ_LOG(3, (THIS_FILE, "..pool speedup over malloc best=%dx, worst=%dx", 
			  (int)(malloc_time/best),
			  (int)(malloc_time/worst)));
    return 0;
}


#endif	/* INCLUDE_POOL_PERF_TEST */

