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
diff --git a/pjlib/include/pj/pool.h b/pjlib/include/pj/pool.h
index 3d3215c..7f7fd2b 100644
--- a/pjlib/include/pj/pool.h
+++ b/pjlib/include/pj/pool.h
@@ -449,6 +449,32 @@
      * @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);
+
 };
 
 /**
@@ -557,6 +583,17 @@
     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.
      */
     pj_list	    free_list[PJ_CACHING_POOL_ARRAY_SIZE];
diff --git a/pjlib/src/pj/pool_caching.c b/pjlib/src/pj/pool_caching.c
index 581b577..e0eecd4 100644
--- a/pjlib/src/pj/pool_caching.c
+++ b/pjlib/src/pj/pool_caching.c
@@ -31,6 +31,9 @@
 				    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 @@
     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 @@
 #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 7387bec..20f925a 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);
 }