Index: apc_sma.c =================================================================== RCS file: /repository/pecl/apc/apc_sma.c,v retrieving revision 1.62 diff -u -r1.62 apc_sma.c --- apc_sma.c 14 Mar 2007 11:28:49 -0000 1.62 +++ apc_sma.c 1 Apr 2007 00:03:38 -0000 @@ -77,11 +77,15 @@ static volatile size_t block_id = 0; #endif +#define APC_SMA_CANARIES 1 + typedef struct block_t block_t; struct block_t { size_t size; /* size of this block */ size_t next; /* offset in segment of next free block */ +#ifdef APC_SMA_CANARIES size_t canary; /* canary to check for memory overwrites */ +#endif #ifdef __APC_SMA_DEBUG__ size_t id; /* identifier for the memory block */ #endif @@ -95,21 +99,26 @@ #define OFFSET(block) ((size_t)(((char*)block) - (char*)shmaddr)) /* Canary macros for setting, checking and resetting memory canaries */ -#define SET_CANARY(v) (v)->canary = 0x42424242 -#define CHECK_CANARY(v) assert((v)->canary == 0x42424242) -#define RESET_CANARY(v) (v)->canary = -42 +#ifdef APC_SMA_CANARIES + #define SET_CANARY(v) (v)->canary = 0x42424242 + #define CHECK_CANARY(v) assert((v)->canary == 0x42424242) + #define RESET_CANARY(v) (v)->canary = -42 +#else + #define SET_CANARY(v) + #define CHECK_CANARY(v) + #define RESET_CANARY(v) +#endif + #ifdef max #undef max #endif #define max(a, b) ((a) > (b) ? (a) : (b)) -/* {{{ alignword: returns x, aligned to the system's word boundary */ -static int alignword(int x) -{ - typedef union { void* p; int i; long l; double d; void (*f)(); } word_t; - return sizeof(word_t) * (1 + ((x-1)/sizeof(word_t))); -} +/* {{{ ALIGNWORD: returns x, aligned to the system's word boundary */ +typedef union { void* p; int i; long l; double d; void (*f)(); } word_t; +#define ALIGNWORD(x) (sizeof(word_t) * (1 + (((x)-1)/sizeof(word_t)))) +#define MINBLOCKSIZE (ALIGNWORD(1) + ALIGNWORD(sizeof(block_t))) /* }}} */ /* {{{ sma_allocate: tries to allocate size bytes in a segment */ @@ -122,9 +131,9 @@ size_t realsize; /* actual size of block needed, including header */ size_t last_offset; /* save the last search offset */ int wrapped=0; - size_t block_size = alignword(sizeof(struct block_t)); + const size_t block_size = ALIGNWORD(sizeof(struct block_t)); - realsize = alignword(size + block_size); + realsize = ALIGNWORD(size + block_size); /* * First, insure that the segment contains at least realsize free bytes, @@ -153,7 +162,7 @@ CHECK_CANARY(cur); #endif /* If it fits perfectly or it fits after a split, stop searching */ - if (cur->size == realsize || (cur->size > (block_size + realsize))) { + if (cur->size >= realsize) { prvnextfit = prv; break; } @@ -183,13 +192,7 @@ CHECK_CANARY(prv); CHECK_CANARY(cur); - /* update the block header */ - header->avail -= realsize; -#if ALLOC_DISTRIBUTION - header->adist[(int)(log(size)/log(2))]++; -#endif - - if (cur->size == realsize) { + if (cur->size == realsize || (cur->size > realsize && cur->size < (realsize + (MINBLOCKSIZE * 2)))) { /* cur is a perfect fit for realsize; just unlink it */ prv->next = cur->next; } @@ -211,6 +214,13 @@ nxt->id = -1; #endif } + + /* update the block header */ + header->avail -= cur->size; +#if ALLOC_DISTRIBUTION + header->adist[(int)(log(size)/log(2))]++; +#endif + header->nfoffset = last_offset; SET_CANARY(cur); @@ -232,7 +242,7 @@ block_t* nxt; /* the block after cur */ size_t size; /* size of deallocated block */ - offset -= alignword(sizeof(struct block_t)); + offset -= ALIGNWORD(sizeof(struct block_t)); assert(offset >= 0); /* find position of new block in free list */ @@ -345,7 +355,7 @@ apc_lck_create(NULL, 0, 1, header->sma_lock); header->segsize = sma_segsize; header->avail = sma_segsize - sizeof(header_t) - sizeof(block_t) - - alignword(sizeof(int)); + ALIGNWORD(sizeof(int)); header->nfoffset = 0; #if ALLOC_DISTRIBUTION { @@ -500,7 +510,7 @@ info = (apc_sma_info_t*) apc_emalloc(sizeof(apc_sma_info_t)); info->num_seg = sma_numseg; - info->seg_size = sma_segsize - sizeof(header_t) - sizeof(block_t) - alignword(sizeof(int)); + info->seg_size = sma_segsize - sizeof(header_t) - sizeof(block_t) - ALIGNWORD(sizeof(int)); info->list = apc_emalloc(info->num_seg * sizeof(apc_sma_link_t*)); for (i = 0; i < sma_numseg; i++) {