diff options
-rw-r--r-- | misc/apr_rmm.c | 27 | ||||
-rw-r--r-- | test/testrmm.c | 20 |
2 files changed, 34 insertions, 13 deletions
diff --git a/misc/apr_rmm.c b/misc/apr_rmm.c index a4accb07..e0fedad9 100644 --- a/misc/apr_rmm.c +++ b/misc/apr_rmm.c @@ -33,6 +33,9 @@ typedef struct rmm_hdr_block_t { apr_rmm_off_t /* rmm_block_t */ firstfree; } rmm_hdr_block_t; +#define RMM_HDR_BLOCK_SIZE (APR_ALIGN_DEFAULT(sizeof(rmm_hdr_block_t))) +#define RMM_BLOCK_SIZE (APR_ALIGN_DEFAULT(sizeof(rmm_block_t))) + struct apr_rmm_t { apr_pool_t *p; rmm_hdr_block_t *base; @@ -87,7 +90,7 @@ static apr_rmm_off_t find_block_of_size(apr_rmm_t *rmm, apr_size_t size) next = blk->next; } - if (bestsize > sizeof(rmm_block_t) + size) { + if (bestsize > RMM_BLOCK_SIZE + size) { struct rmm_block_t *blk = (rmm_block_t*)((char*)rmm->base + best); struct rmm_block_t *new = (rmm_block_t*)((char*)rmm->base + best + size); @@ -205,7 +208,7 @@ APU_DECLARE(apr_status_t) apr_rmm_init(apr_rmm_t **rmm, apr_anylock_t *lock, (*rmm)->base->abssize = size; (*rmm)->base->firstused = 0; - (*rmm)->base->firstfree = sizeof(rmm_hdr_block_t); + (*rmm)->base->firstfree = RMM_HDR_BLOCK_SIZE; blk = (rmm_block_t *)((char*)base + (*rmm)->base->firstfree); @@ -281,15 +284,15 @@ APU_DECLARE(apr_rmm_off_t) apr_rmm_malloc(apr_rmm_t *rmm, apr_size_t reqsize) { apr_rmm_off_t this; - reqsize = APR_ALIGN_DEFAULT(reqsize); + reqsize = APR_ALIGN_DEFAULT(reqsize) + RMM_BLOCK_SIZE; APR_ANYLOCK_LOCK(&rmm->lock); - this = find_block_of_size(rmm, reqsize + sizeof(rmm_block_t)); + this = find_block_of_size(rmm, reqsize); if (this) { move_block(rmm, this, 0); - this += sizeof(rmm_block_t); + this += RMM_BLOCK_SIZE; } APR_ANYLOCK_UNLOCK(&rmm->lock); @@ -300,16 +303,16 @@ APU_DECLARE(apr_rmm_off_t) apr_rmm_calloc(apr_rmm_t *rmm, apr_size_t reqsize) { apr_rmm_off_t this; - reqsize = APR_ALIGN_DEFAULT(reqsize); + reqsize = APR_ALIGN_DEFAULT(reqsize) + RMM_BLOCK_SIZE; APR_ANYLOCK_LOCK(&rmm->lock); - this = find_block_of_size(rmm, reqsize + sizeof(rmm_block_t)); + this = find_block_of_size(rmm, reqsize); if (this) { move_block(rmm, this, 0); - this += sizeof(rmm_block_t); - memset((char*)rmm->base + this, 0, reqsize); + this += RMM_BLOCK_SIZE; + memset((char*)rmm->base + this, 0, reqsize - RMM_BLOCK_SIZE); } APR_ANYLOCK_UNLOCK(&rmm->lock); @@ -353,11 +356,11 @@ APU_DECLARE(apr_status_t) apr_rmm_free(apr_rmm_t *rmm, apr_rmm_off_t this) /* A little sanity check is always healthy, especially here. * If we really cared, we could make this compile-time */ - if (this < sizeof(rmm_hdr_block_t) + sizeof(rmm_block_t)) { + if (this < RMM_HDR_BLOCK_SIZE + RMM_BLOCK_SIZE) { return APR_EINVAL; } - this -= sizeof(rmm_block_t); + this -= RMM_BLOCK_SIZE; blk = (rmm_block_t*)((char*)rmm->base + this); @@ -413,5 +416,5 @@ APU_DECLARE(apr_rmm_off_t) apr_rmm_offset_get(apr_rmm_t *rmm, void* entity) APU_DECLARE(apr_size_t) apr_rmm_overhead_get(int n) { - return sizeof(rmm_hdr_block_t) + n * sizeof(rmm_block_t); + return RMM_HDR_BLOCK_SIZE + n * RMM_BLOCK_SIZE; } diff --git a/test/testrmm.c b/test/testrmm.c index c4dc989f..8203be16 100644 --- a/test/testrmm.c +++ b/test/testrmm.c @@ -51,7 +51,7 @@ static apr_status_t test_rmm(apr_pool_t *parpool) } /* We're going to want 10 blocks of data from our target rmm. */ - size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT); + size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1); printf("Creating anonymous shared memory (%" APR_SIZE_T_FMT " bytes).....", size); rv = apr_shm_create(&shm, size, NULL, pool); @@ -87,6 +87,24 @@ static apr_status_t test_rmm(apr_pool_t *parpool) else { return APR_EGENERAL; } + + printf("Checking each fragment for address alignment....."); + for (i = 0; i < FRAG_COUNT; i++) { + char *c = apr_rmm_addr_get(rmm, off[i]); + apr_size_t sc = (apr_size_t)c; + + if (off[i] == 0) { + printf("allocation failed for offset %d\n", i); + return APR_ENOMEM; + } + + if (sc & 7) { + printf("Bad alignment for fragment %d; %p not %p!\n", + i, c, (void *)APR_ALIGN_DEFAULT((apr_size_t)c)); + return APR_EGENERAL; + } + } + fprintf(stdout, "OK\n"); printf("Setting each fragment to a unique value.........."); for (i = 0; i < FRAG_COUNT; i++) { |