summaryrefslogtreecommitdiff
path: root/pjlib/src
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-01-29 10:10:49 +0000
committerBenny Prijono <bennylp@teluu.com>2010-01-29 10:10:49 +0000
commit8e54a92b6eb6302761fd9a1949086baa26e0007a (patch)
tree7aa9a3938e8fb52cb2970c25ed16e3091af2a9f8 /pjlib/src
parent700fa9dc82720fbca9eacd67b7106ad254595911 (diff)
Fixed ticket #1037: Memory pool alignment error when alignment is set to be greater than the default (thanks John Ridges for the report):
- fixed the pool allocation routines in PJLIB, - add alignment test in pjlib-test (only useful if PJ_POOL_ALIGNMENT is configured in config_site.h), - fixed other pool tests in pjlib-test which are broken when PJ_POOL_ALIGNMENT is enlarged git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3081 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src')
-rw-r--r--pjlib/src/pj/pool.c15
-rw-r--r--pjlib/src/pjlib-test/pool.c114
-rw-r--r--pjlib/src/pjlib-test/pool_perf.c6
3 files changed, 131 insertions, 4 deletions
diff --git a/pjlib/src/pj/pool.c b/pjlib/src/pj/pool.c
index 5b022a8c..22df21c6 100644
--- a/pjlib/src/pj/pool.c
+++ b/pjlib/src/pj/pool.c
@@ -212,8 +212,14 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,
/* Create the first block from the memory. */
block = (pj_pool_block*) (buffer + sizeof(*pool));
- block->cur = block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);
+ block->buf = ((unsigned char*)block) + sizeof(pj_pool_block);
block->end = buffer + initial_size;
+
+ /* Set the start pointer, aligning it as needed */
+ block->cur = (unsigned char*)
+ (((unsigned long)block->buf + PJ_POOL_ALIGNMENT - 1) &
+ ~(PJ_POOL_ALIGNMENT - 1));
+
pj_list_insert_after(&pool->block_list, block);
pj_pool_init_int(pool, name, increment_size, callback);
@@ -254,7 +260,12 @@ static void reset_pool(pj_pool_t *pool)
}
block = pool->block_list.next;
- block->cur = block->buf;
+
+ /* Set the start pointer, aligning it as needed */
+ block->cur = (unsigned char*)
+ (((unsigned long)block->buf + PJ_POOL_ALIGNMENT - 1) &
+ ~(PJ_POOL_ALIGNMENT - 1));
+
pool->capacity = block->end - (unsigned char*)pool;
}
diff --git a/pjlib/src/pjlib-test/pool.c b/pjlib/src/pjlib-test/pool.c
index ce91ac6e..930e552e 100644
--- a/pjlib/src/pjlib-test/pool.c
+++ b/pjlib/src/pjlib-test/pool.c
@@ -79,6 +79,112 @@ static int capacity_test(void)
return 0;
}
+/* Test that the alignment works. */
+static int pool_alignment_test(void)
+{
+ pj_pool_t *pool;
+ void *ptr;
+
+ PJ_LOG(3,("test", "...alignment test"));
+
+ pool = pj_pool_create(mem, NULL, PJ_POOL_SIZE+64, 64, NULL);
+ if (!pool)
+ return -300;
+
+#define IS_ALIGNED(p) ((((unsigned long)p) & (PJ_POOL_ALIGNMENT-1)) == 0)
+
+ /* Test first allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -310;
+ }
+
+ /* Test subsequent allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -320;
+ }
+
+ /* Test allocation after new block is created */
+ ptr = pj_pool_alloc(pool, 127);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -330;
+ }
+
+ /* Reset the pool */
+ pj_pool_reset(pool);
+
+ /* Retest first allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -340;
+ }
+
+ /* Retest subsequent allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -350;
+ }
+
+ /* Done */
+ pj_pool_release(pool);
+
+ return 0;
+}
+
+/* Test that the alignment works for pool on buf. */
+static int pool_buf_alignment_test(void)
+{
+ pj_pool_t *pool;
+ char buf[256];
+ void *ptr;
+
+ PJ_LOG(3,("test", "...pool_buf alignment test"));
+
+ pool = pj_pool_create_on_buf(NULL, buf, sizeof(buf));
+ if (!pool)
+ return -400;
+
+ /* Test first allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -410;
+ }
+
+ /* Test subsequent allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -420;
+ }
+
+ /* Reset the pool */
+ pj_pool_reset(pool);
+
+ /* Retest first allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -430;
+ }
+
+ /* Retest subsequent allocation */
+ ptr = pj_pool_alloc(pool, 1);
+ if (!IS_ALIGNED(ptr)) {
+ pj_pool_release(pool);
+ return -440;
+ }
+
+ /* Done */
+ return 0;
+}
+
/* Test function to drain the pool's space.
*/
static int drain_test(pj_size_t size, pj_size_t increment)
@@ -149,7 +255,7 @@ static int pool_buf_test(void)
enum { STATIC_BUF_SIZE = 40 };
/* 16 is the internal struct in pool_buf */
static char buf[ STATIC_BUF_SIZE + sizeof(pj_pool_t) +
- sizeof(pj_pool_block) + 16];
+ sizeof(pj_pool_block) + 2 * PJ_POOL_ALIGNMENT];
pj_pool_t *pool;
void *p;
PJ_USE_EXCEPTION;
@@ -200,6 +306,12 @@ int pool_test(void)
rc = capacity_test();
if (rc) return rc;
+ rc = pool_alignment_test();
+ if (rc) return rc;
+
+ rc = pool_buf_alignment_test();
+ if (rc) return rc;
+
for (loop=0; loop<LOOP; ++loop) {
/* Test that the pool should grow automaticly. */
rc = drain_test(SIZE, SIZE);
diff --git a/pjlib/src/pjlib-test/pool_perf.c b/pjlib/src/pjlib-test/pool_perf.c
index 8bd5635f..d73f7a5b 100644
--- a/pjlib/src/pjlib-test/pool_perf.c
+++ b/pjlib/src/pjlib-test/pool_perf.c
@@ -127,8 +127,12 @@ int pool_perf_test()
/* 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);
- total_size += sizes[i];
+ 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 */