From c6e165f8d129e5e2f8840f076a54a0750a7c6a4f Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 9 Jul 2006 10:05:46 +0000 Subject: [PATCH] Added feature to report peak memory used in caching pool git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@594 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/pool.h | 37 +++++++++++++++++++++++++++++++ pjlib/src/pj/pool_caching.c | 33 +++++++++++++++++++++++++++ pjlib/src/pj/pool_policy_malloc.c | 30 +++++++++++++++++++------ 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/pjlib/include/pj/pool.h b/pjlib/include/pj/pool.h index 3d3215c9b..7f7fd2b36 100644 --- a/pjlib/include/pj/pool.h +++ b/pjlib/include/pj/pool.h @@ -449,6 +449,32 @@ struct pj_pool_factory * @param factory The pool factory. */ void (*dump_status)( pj_pool_factory *factory, pj_bool_t detail ); + + /** + * This is optional callback to be called by allocation policy when + * it allocates a new memory block. The factory may use this callback + * for example to keep track of the total number of memory blocks + * currently allocated by applications. + * + * @param factory The pool factory. + * @param size Size requested by application. + * + * @return MUST return PJ_TRUE, otherwise the block + * allocation is cancelled. + */ + pj_bool_t (*on_block_alloc)(pj_pool_factory *factory, pj_size_t size); + + /** + * This is optional callback to be called by allocation policy when + * it frees memory block. The factory may use this callback + * for example to keep track of the total number of memory blocks + * currently allocated by applications. + * + * @param factory The pool factory. + * @param size Size freed. + */ + void (*on_block_free)(pj_pool_factory *factory, pj_size_t size); + }; /** @@ -556,6 +582,17 @@ struct pj_caching_pool */ pj_size_t used_count; + /** + * Total size of memory currently used by application. + */ + pj_size_t used_size; + + /** + * The maximum size of memory used by application throughout the life + * of the caching pool. + */ + pj_size_t peak_used_size; + /** * Lists of pools in the cache, indexed by pool size. */ diff --git a/pjlib/src/pj/pool_caching.c b/pjlib/src/pj/pool_caching.c index 581b577fd..e0eecd4d1 100644 --- a/pjlib/src/pj/pool_caching.c +++ b/pjlib/src/pj/pool_caching.c @@ -31,6 +31,9 @@ static pj_pool_t* cpool_create_pool(pj_pool_factory *pf, pj_pool_callback *callback); static void cpool_release_pool(pj_pool_factory *pf, pj_pool_t *pool); static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail ); +static pj_bool_t cpool_on_block_alloc(pj_pool_factory *f, pj_size_t sz); +static void cpool_on_block_free(pj_pool_factory *f, pj_size_t sz); + static pj_size_t pool_sizes[PJ_CACHING_POOL_ARRAY_SIZE] = { @@ -63,6 +66,8 @@ PJ_DEF(void) pj_caching_pool_init( pj_caching_pool *cp, cp->factory.create_pool = &cpool_create_pool; cp->factory.release_pool = &cpool_release_pool; cp->factory.dump_status = &cpool_dump_status; + cp->factory.on_block_alloc = &cpool_on_block_alloc; + cp->factory.on_block_free = &cpool_on_block_free; cp->pool = pj_pool_create_int(&cp->factory, "cachingpool", 256, 0, NULL); @@ -273,5 +278,33 @@ static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail ) #endif } + +static pj_bool_t cpool_on_block_alloc(pj_pool_factory *f, pj_size_t sz) +{ + pj_caching_pool *cp = (pj_caching_pool*)f; + + //Can't lock because mutex is not recursive + //if (cp->mutex) pj_mutex_lock(cp->mutex); + + cp->used_size += sz; + if (cp->used_size > cp->peak_used_size) + cp->peak_used_size = cp->used_size; + + //if (cp->mutex) pj_mutex_unlock(cp->mutex); + + return PJ_TRUE; +} + + +static void cpool_on_block_free(pj_pool_factory *f, pj_size_t sz) +{ + pj_caching_pool *cp = (pj_caching_pool*)f; + + //pj_mutex_lock(cp->mutex); + cp->used_size -= sz; + //pj_mutex_unlock(cp->mutex); +} + + #endif /* PJ_HAS_POOL_ALT_API */ diff --git a/pjlib/src/pj/pool_policy_malloc.c b/pjlib/src/pj/pool_policy_malloc.c index 7387bec48..20f925a76 100644 --- a/pjlib/src/pj/pool_policy_malloc.c +++ b/pjlib/src/pj/pool_policy_malloc.c @@ -30,18 +30,34 @@ static void *default_block_alloc(pj_pool_factory *factory, pj_size_t size) { - PJ_CHECK_STACK(); - PJ_UNUSED_ARG(factory); - PJ_UNUSED_ARG(size); + void *p; - return malloc(size); + PJ_CHECK_STACK(); + + if (factory->on_block_alloc) { + int rc; + rc = factory->on_block_alloc(factory, size); + if (!rc) + return NULL; + } + + p = malloc(size); + + if (p == NULL) { + if (factory->on_block_free) + factory->on_block_free(factory, size); + } + + return p; } -static void default_block_free(pj_pool_factory *factory, void *mem, pj_size_t size) +static void default_block_free(pj_pool_factory *factory, void *mem, + pj_size_t size) { PJ_CHECK_STACK(); - PJ_UNUSED_ARG(factory); - PJ_UNUSED_ARG(size); + + if (factory->on_block_free) + factory->on_block_free(factory, size); free(mem); }