fixed strict aliasing issues in xma.c
This commit is contained in:
@ -87,7 +87,7 @@ typedef struct hawk_xma_t hawk_xma_t;
|
|||||||
typedef struct hawk_xma_fblk_t hawk_xma_fblk_t;
|
typedef struct hawk_xma_fblk_t hawk_xma_fblk_t;
|
||||||
typedef struct hawk_xma_mblk_t hawk_xma_mblk_t;
|
typedef struct hawk_xma_mblk_t hawk_xma_mblk_t;
|
||||||
|
|
||||||
#define HAWK_XMA_FIXED 32
|
#define HAWK_XMA_FIXED (32)
|
||||||
#define HAWK_XMA_SIZE_BITS ((HAWK_SIZEOF_OOW_T*8)-1)
|
#define HAWK_XMA_SIZE_BITS ((HAWK_SIZEOF_OOW_T*8)-1)
|
||||||
|
|
||||||
struct hawk_xma_t
|
struct hawk_xma_t
|
||||||
|
179
lib/xma.c
179
lib/xma.c
@ -62,15 +62,29 @@ $1 = (hawk_int_t *) 0x7fffea722f78
|
|||||||
#define FIXED HAWK_XMA_FIXED
|
#define FIXED HAWK_XMA_FIXED
|
||||||
#define XFIMAX(xma) (HAWK_COUNTOF(xma->xfree)-1)
|
#define XFIMAX(xma) (HAWK_COUNTOF(xma->xfree)-1)
|
||||||
|
|
||||||
|
#define fblk_free(b) (((hawk_xma_fblk_t*)(b))->free)
|
||||||
|
#define fblk_size(b) (((hawk_xma_fblk_t*)(b))->size)
|
||||||
|
#define fblk_prev_size(b) (((hawk_xma_fblk_t*)(b))->prev_size)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define mblk_free(b) (((hawk_xma_mblk_t*)(b))->free)
|
||||||
#define mblk_size(b) (((hawk_xma_mblk_t*)(b))->size)
|
#define mblk_size(b) (((hawk_xma_mblk_t*)(b))->size)
|
||||||
#define mblk_prev_size(b) (((hawk_xma_mblk_t*)(b))->prev_size)
|
#define mblk_prev_size(b) (((hawk_xma_mblk_t*)(b))->prev_size)
|
||||||
|
#else
|
||||||
|
/* Let mblk_free(), mblk_size(), mblk_prev_size() be an alias to
|
||||||
|
* fblk_free(), fblk_size(), fblk_prev_size() to follow strict aliasing rule.
|
||||||
|
* if gcc/clang is used, specifying __attribute__((__may_alias__)) to hawk_xma_mblk_t
|
||||||
|
* and hawk_xma_fblk_t would also work. */
|
||||||
|
#define mblk_free(b) fblk_free(b)
|
||||||
|
#define mblk_size(b) fblk_size(b)
|
||||||
|
#define mblk_prev_size(b) fblk_prev_size(b)
|
||||||
|
#endif
|
||||||
#define next_mblk(b) ((hawk_xma_mblk_t*)((hawk_uint8_t*)b + MBLKHDRSIZE + mblk_size(b)))
|
#define next_mblk(b) ((hawk_xma_mblk_t*)((hawk_uint8_t*)b + MBLKHDRSIZE + mblk_size(b)))
|
||||||
#define prev_mblk(b) ((hawk_xma_mblk_t*)((hawk_uint8_t*)b - (MBLKHDRSIZE + mblk_prev_size(b))))
|
#define prev_mblk(b) ((hawk_xma_mblk_t*)((hawk_uint8_t*)b - (MBLKHDRSIZE + mblk_prev_size(b))))
|
||||||
|
|
||||||
struct hawk_xma_mblk_t
|
struct hawk_xma_mblk_t
|
||||||
{
|
{
|
||||||
hawk_oow_t prev_size;
|
hawk_oow_t prev_size;
|
||||||
|
|
||||||
/* the block size is shifted by 1 bit and the maximum value is
|
/* the block size is shifted by 1 bit and the maximum value is
|
||||||
* offset by 1 bit because of the 'free' bit-field.
|
* offset by 1 bit because of the 'free' bit-field.
|
||||||
* i could keep 'size' without shifting with bit manipulation
|
* i could keep 'size' without shifting with bit manipulation
|
||||||
@ -84,11 +98,12 @@ struct hawk_xma_mblk_t
|
|||||||
|
|
||||||
struct hawk_xma_fblk_t
|
struct hawk_xma_fblk_t
|
||||||
{
|
{
|
||||||
hawk_oow_t prev_size;
|
hawk_oow_t prev_size; /**< size of the previous block */
|
||||||
hawk_oow_t free: 1;
|
hawk_oow_t free: 1;
|
||||||
hawk_oow_t size: HAWK_XMA_SIZE_BITS;/**< block size */
|
hawk_oow_t size: HAWK_XMA_SIZE_BITS;/**< block size */
|
||||||
|
|
||||||
/* these two fields are used only if the block is free */
|
/* the fields are must be identical to the fields of hawk_xma_mblk_t */
|
||||||
|
/* the two fields below are used only if the block is free */
|
||||||
hawk_xma_fblk_t* free_prev; /**< link to the previous free block */
|
hawk_xma_fblk_t* free_prev; /**< link to the previous free block */
|
||||||
hawk_xma_fblk_t* free_next; /**< link to the next free block */
|
hawk_xma_fblk_t* free_next; /**< link to the next free block */
|
||||||
};
|
};
|
||||||
@ -187,7 +202,6 @@ static HAWK_INLINE hawk_oow_t getxfi (hawk_xma_t* xma, hawk_oow_t size)
|
|||||||
return xfi;
|
return xfi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hawk_xma_t* hawk_xma_open (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, void* zoneptr, hawk_oow_t zonesize)
|
hawk_xma_t* hawk_xma_open (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, void* zoneptr, hawk_oow_t zonesize)
|
||||||
{
|
{
|
||||||
hawk_xma_t* xma;
|
hawk_xma_t* xma;
|
||||||
@ -326,7 +340,6 @@ static HAWK_INLINE void detach_from_freelist (hawk_xma_t* xma, hawk_xma_fblk_t*
|
|||||||
{
|
{
|
||||||
/* the previous item does not exist. the block is the first
|
/* the previous item does not exist. the block is the first
|
||||||
* item in the free list. */
|
* item in the free list. */
|
||||||
|
|
||||||
hawk_oow_t xfi = getxfi(xma, b->size);
|
hawk_oow_t xfi = getxfi(xma, b->size);
|
||||||
HAWK_ASSERT(b == xma->xfree[xfi]);
|
HAWK_ASSERT(b == xma->xfree[xfi]);
|
||||||
/* let's update the free list head */
|
/* let's update the free list head */
|
||||||
@ -412,7 +425,7 @@ static hawk_xma_fblk_t* alloc_from_freelist (hawk_xma_t* xma, hawk_oow_t xfi, ha
|
|||||||
void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
||||||
{
|
{
|
||||||
hawk_xma_fblk_t* cand;
|
hawk_xma_fblk_t* cand;
|
||||||
hawk_oow_t xfi;
|
hawk_oow_t xfi, native_xfi;
|
||||||
|
|
||||||
DBG_VERIFY(xma, "alloc start");
|
DBG_VERIFY(xma, "alloc start");
|
||||||
|
|
||||||
@ -425,6 +438,7 @@ void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
|||||||
|
|
||||||
HAWK_ASSERT(size >= ALIGN);
|
HAWK_ASSERT(size >= ALIGN);
|
||||||
xfi = getxfi(xma, size);
|
xfi = getxfi(xma, size);
|
||||||
|
native_xfi = xfi;
|
||||||
|
|
||||||
/*if (xfi < XFIMAX(xma) && xma->xfree[xfi])*/
|
/*if (xfi < XFIMAX(xma) && xma->xfree[xfi])*/
|
||||||
if (xfi < FIXED && xma->xfree[xfi])
|
if (xfi < FIXED && xma->xfree[xfi])
|
||||||
@ -485,6 +499,15 @@ void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
|||||||
cand = alloc_from_freelist(xma, xfi, size);
|
cand = alloc_from_freelist(xma, xfi, size);
|
||||||
if (cand) break;
|
if (cand) break;
|
||||||
}
|
}
|
||||||
|
if (!cand)
|
||||||
|
{
|
||||||
|
/* try fixed-sized free chains */
|
||||||
|
for (xfi = native_xfi + 1; xfi < FIXED; xfi++)
|
||||||
|
{
|
||||||
|
cand = alloc_from_freelist(xma, xfi, size);
|
||||||
|
if (cand) break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!cand)
|
if (!cand)
|
||||||
{
|
{
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
@ -494,6 +517,7 @@ void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.nallocgoodops++;
|
xma->stat.nallocgoodops++;
|
||||||
@ -504,52 +528,51 @@ void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
|||||||
|
|
||||||
static void* _realloc_merge (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
static void* _realloc_merge (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* blk = (hawk_xma_mblk_t*)USR_TO_SYS(b);
|
hawk_uint8_t* blk = (hawk_uint8_t*)USR_TO_SYS(b);
|
||||||
|
|
||||||
DBG_VERIFY(xma, "realloc merge start");
|
DBG_VERIFY(xma, "realloc merge start");
|
||||||
/* rounds up 'size' to be multiples of ALIGN */
|
/* rounds up 'size' to be multiples of ALIGN */
|
||||||
if (size < MINALLOCSIZE) size = MINALLOCSIZE;
|
if (size < MINALLOCSIZE) size = MINALLOCSIZE;
|
||||||
size = HAWK_ALIGN_POW2(size, ALIGN);
|
size = HAWK_ALIGN_POW2(size, ALIGN);
|
||||||
|
|
||||||
if (size > blk->size)
|
if (size > mblk_size(blk))
|
||||||
{
|
{
|
||||||
/* grow the current block */
|
/* grow the current block */
|
||||||
hawk_oow_t req;
|
hawk_oow_t req;
|
||||||
hawk_xma_mblk_t* n;
|
hawk_uint8_t* n;
|
||||||
hawk_oow_t rem;
|
hawk_oow_t rem;
|
||||||
|
|
||||||
req = size - blk->size; /* required size additionally */
|
req = size - mblk_size(blk); /* required size additionally */
|
||||||
|
|
||||||
n = next_mblk(blk);
|
n = (hawk_uint8_t*)next_mblk(blk);
|
||||||
/* check if the next adjacent block is available */
|
/* check if the next adjacent block is available */
|
||||||
if ((hawk_uint8_t*)n >= xma->end || !n->free || req > n->size) return HAWK_NULL; /* no! */
|
if (n >= xma->end || !mblk_free(n) || req > mblk_size(n)) return HAWK_NULL; /* no! */
|
||||||
/* TODO: check more blocks if the next block is free but small in size.
|
/* TODO: check more blocks if the next block is free but small in size.
|
||||||
* check the previous adjacent blocks also */
|
* check the previous adjacent blocks also */
|
||||||
|
|
||||||
HAWK_ASSERT(blk->size == n->prev_size);
|
HAWK_ASSERT(mblk_size(blk) == mblk_prev_size(n));
|
||||||
|
|
||||||
/* let's merge the current block with the next block */
|
/* let's merge the current block with the next block */
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)n);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)n);
|
||||||
|
|
||||||
rem = (MBLKHDRSIZE + n->size) - req;
|
rem = (MBLKHDRSIZE + mblk_size(n)) - req;
|
||||||
if (rem >= FBLKMINSIZE)
|
if (rem >= FBLKMINSIZE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* the remaining part of the next block is large enough
|
* the remaining part of the next block is large enough
|
||||||
* to hold a block. break the next block.
|
* to hold a block. break the next block.
|
||||||
*/
|
*/
|
||||||
|
hawk_uint8_t* y, * z;
|
||||||
|
|
||||||
hawk_xma_mblk_t* y, * z;
|
mblk_size(blk) += req;
|
||||||
|
y = (hawk_uint8_t*)next_mblk(blk);
|
||||||
blk->size += req;
|
mblk_free(y) = 1;
|
||||||
y = next_mblk(blk);
|
mblk_size(y) = rem - MBLKHDRSIZE;
|
||||||
y->free = 1;
|
mblk_prev_size(y) = mblk_size(blk);
|
||||||
y->size = rem - MBLKHDRSIZE;
|
|
||||||
y->prev_size = blk->size;
|
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
||||||
|
|
||||||
z = next_mblk(y);
|
z = (hawk_uint8_t*)next_mblk(y);
|
||||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = y->size;
|
if (z < xma->end) mblk_prev_size(z) = mblk_size(y);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.alloc += req;
|
xma->stat.alloc += req;
|
||||||
@ -559,54 +582,54 @@ static void* _realloc_merge (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* z;
|
hawk_uint8_t* z;
|
||||||
|
|
||||||
/* the remaining part of the next block is too small to form an indepent block.
|
/* the remaining part of the next block is too small to form an indepent block.
|
||||||
* utilize the whole block by merging to the resizing block */
|
* utilize the whole block by merging to the resizing block */
|
||||||
blk->size += MBLKHDRSIZE + n->size;
|
mblk_size(blk) += MBLKHDRSIZE + mblk_size(n);
|
||||||
|
|
||||||
z = next_mblk(blk);
|
z = (hawk_uint8_t*)next_mblk(blk);
|
||||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = blk->size;
|
if (z < xma->end) mblk_prev_size(z) = mblk_size(blk);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.nfree--;
|
xma->stat.nfree--;
|
||||||
xma->stat.alloc += MBLKHDRSIZE + n->size;
|
xma->stat.alloc += MBLKHDRSIZE + mblk_size(n);
|
||||||
xma->stat.avail -= n->size;
|
xma->stat.avail -= mblk_size(n);
|
||||||
if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc;
|
if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (size < blk->size)
|
else if (size < mblk_size(blk))
|
||||||
{
|
{
|
||||||
/* shrink the block */
|
/* shrink the block */
|
||||||
hawk_oow_t rem = blk->size - size;
|
hawk_oow_t rem = mblk_size(blk) - size;
|
||||||
if (rem >= FBLKMINSIZE)
|
if (rem >= FBLKMINSIZE)
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* n;
|
hawk_uint8_t* n;
|
||||||
|
|
||||||
n = next_mblk(blk);
|
n = (hawk_uint8_t*)next_mblk(blk);
|
||||||
|
|
||||||
/* the leftover is large enough to hold a block of minimum size.split the current block */
|
/* the leftover is large enough to hold a block of minimum size.split the current block */
|
||||||
if ((hawk_uint8_t*)n < xma->end && n->free)
|
if (n < xma->end && mblk_free(n))
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* y, * z;
|
hawk_uint8_t* y, * z;
|
||||||
|
|
||||||
/* make the leftover block merge with the next block */
|
/* make the leftover block merge with the next block */
|
||||||
|
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)n);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)n);
|
||||||
|
|
||||||
blk->size = size;
|
mblk_size(blk) = size;
|
||||||
|
|
||||||
y = next_mblk(blk); /* update y to the leftover block with the new block size set above */
|
y = (hawk_uint8_t*)next_mblk(blk); /* update y to the leftover block with the new block size set above */
|
||||||
y->free = 1;
|
mblk_free(y) = 1;
|
||||||
y->size = rem + n->size; /* add up the adjust block - (rem + MBLKHDRSIZE(n) + n->size) - MBLKHDRSIZE(y) */
|
mblk_size(y) = rem + mblk_size(n); /* add up the adjust block - (rem + MBLKHDRSIZE(n) + n->size) - MBLKHDRSIZE(y) */
|
||||||
y->prev_size = blk->size;
|
mblk_prev_size(y) = mblk_size(blk);
|
||||||
|
|
||||||
/* add 'y' to the free list */
|
/* add 'y' to the free list */
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
||||||
|
|
||||||
z = next_mblk(y); /* get adjacent block to the merged block */
|
z = (hawk_uint8_t*)next_mblk(y); /* get adjacent block to the merged block */
|
||||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = y->size;
|
if (z < xma->end) mblk_prev_size(z) = mblk_size(y);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.alloc -= rem;
|
xma->stat.alloc -= rem;
|
||||||
@ -615,24 +638,24 @@ static void* _realloc_merge (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* y;
|
hawk_uint8_t* y;
|
||||||
|
|
||||||
/* link the leftover block to the free list */
|
/* link the leftover block to the free list */
|
||||||
blk->size = size;
|
mblk_size(blk) = size;
|
||||||
|
|
||||||
y = next_mblk(blk); /* update y to the leftover block with the new block size set above */
|
y = next_mblk(blk); /* update y to the leftover block with the new block size set above */
|
||||||
y->free = 1;
|
mblk_free(y) = 1;
|
||||||
y->size = rem - MBLKHDRSIZE;
|
mblk_size(y) = rem - MBLKHDRSIZE;
|
||||||
y->prev_size = blk->size;
|
mblk_prev_size(y) = mblk_size(blk);
|
||||||
|
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)y);
|
||||||
/*n = next_mblk(y);
|
/*n = (hawk_uint8_t*)next_mblk(y);
|
||||||
if ((hawk_uint8_t*)n < xma->end)*/ n->prev_size = y->size;
|
if (n < xma->end)*/ mblk_prev_size(n) = mblk_size(y);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.nfree++;
|
xma->stat.nfree++;
|
||||||
xma->stat.alloc -= rem;
|
xma->stat.alloc -= rem;
|
||||||
xma->stat.avail += y->size;
|
xma->stat.avail += mblk_size(y);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,13 +715,13 @@ void* hawk_xma_realloc (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
|||||||
|
|
||||||
void hawk_xma_free (hawk_xma_t* xma, void* b)
|
void hawk_xma_free (hawk_xma_t* xma, void* b)
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* blk = (hawk_xma_mblk_t*)USR_TO_SYS(b);
|
hawk_uint8_t* blk = (hawk_uint8_t*)USR_TO_SYS(b);
|
||||||
hawk_xma_mblk_t* x, * y;
|
hawk_uint8_t* x, * y;
|
||||||
hawk_oow_t org_blk_size;
|
hawk_oow_t org_blk_size;
|
||||||
|
|
||||||
DBG_VERIFY(xma, "free start");
|
DBG_VERIFY(xma, "free start");
|
||||||
|
|
||||||
org_blk_size = blk->size;
|
org_blk_size = mblk_size(blk);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
/* update statistical variables */
|
/* update statistical variables */
|
||||||
@ -707,9 +730,9 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
xma->stat.nfreeops++;
|
xma->stat.nfreeops++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x = prev_mblk(blk);
|
x = (hawk_uint8_t*)prev_mblk(blk);
|
||||||
y = next_mblk(blk);
|
y = (hawk_uint8_t*)next_mblk(blk);
|
||||||
if (((hawk_uint8_t*)x >= xma->start && x->free) && ((hawk_uint8_t*)y < xma->end && y->free))
|
if ((x >= xma->start && mblk_free(x)) && (y < xma->end && mblk_free(y)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Merge the block with surrounding blocks
|
* Merge the block with surrounding blocks
|
||||||
@ -728,25 +751,26 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hawk_xma_mblk_t* z = next_mblk(y);
|
hawk_uint8_t* z;
|
||||||
hawk_oow_t ns = MBLKHDRSIZE + org_blk_size + MBLKHDRSIZE;
|
hawk_oow_t ns = MBLKHDRSIZE + org_blk_size + MBLKHDRSIZE;
|
||||||
hawk_oow_t bs = ns + y->size;
|
/* blk's header size + blk->size + y's header size */
|
||||||
|
hawk_oow_t bs = ns + mblk_size(y);
|
||||||
|
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)x);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)x);
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)y);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)y);
|
||||||
|
|
||||||
x->size += bs;
|
mblk_size(x) += bs;
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)x);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)x);
|
||||||
|
|
||||||
z = next_mblk(x);
|
z = (hawk_uint8_t*)next_mblk(x);
|
||||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = x->size;
|
if ((hawk_uint8_t*)z < xma->end) mblk_prev_size(z) = mblk_size(x);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
xma->stat.nfree--;
|
xma->stat.nfree--;
|
||||||
xma->stat.avail += ns;
|
xma->stat.avail += ns;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if ((hawk_uint8_t*)y < xma->end && y->free)
|
else if (y < xma->end && mblk_free(y))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Merge the block with the next block
|
* Merge the block with the next block
|
||||||
@ -769,18 +793,18 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
hawk_xma_mblk_t* z = next_mblk(y);
|
hawk_uint8_t* z = (hawk_uint8_t*)next_mblk(y);
|
||||||
|
|
||||||
/* detach y from the free list */
|
/* detach y from the free list */
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)y);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)y);
|
||||||
|
|
||||||
/* update the block availability */
|
/* update the block availability */
|
||||||
blk->free = 1;
|
mblk_free(blk) = 1;
|
||||||
/* update the block size. MBLKHDRSIZE for the header space in x */
|
/* update the block size. MBLKHDRSIZE for the header space in x */
|
||||||
blk->size += MBLKHDRSIZE + y->size;
|
mblk_size(blk) += MBLKHDRSIZE + mblk_size(y);
|
||||||
|
|
||||||
/* update the backward link of Y */
|
/* update the backward link of Y */
|
||||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = blk->size;
|
if ((hawk_uint8_t*)z < xma->end) mblk_prev_size(z) = mblk_size(blk);
|
||||||
|
|
||||||
/* attach blk to the free list */
|
/* attach blk to the free list */
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)blk);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)blk);
|
||||||
@ -789,7 +813,7 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
xma->stat.avail += org_blk_size + MBLKHDRSIZE;
|
xma->stat.avail += org_blk_size + MBLKHDRSIZE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if ((hawk_uint8_t*)x >= xma->start && x->free)
|
else if (x >= xma->start && mblk_free(x))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Merge the block with the previous block
|
* Merge the block with the previous block
|
||||||
@ -807,10 +831,10 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
*/
|
*/
|
||||||
detach_from_freelist(xma, (hawk_xma_fblk_t*)x);
|
detach_from_freelist(xma, (hawk_xma_fblk_t*)x);
|
||||||
|
|
||||||
x->size += MBLKHDRSIZE + org_blk_size;
|
mblk_size(x) += MBLKHDRSIZE + org_blk_size;
|
||||||
|
|
||||||
HAWK_ASSERT(y == next_mblk(x));
|
HAWK_ASSERT(y == next_mblk(x));
|
||||||
if ((hawk_uint8_t*)y < xma->end) y->prev_size = x->size;
|
if ((hawk_uint8_t*)y < xma->end) mblk_prev_size(y) = mblk_size(x);
|
||||||
|
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)x);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)x);
|
||||||
|
|
||||||
@ -820,7 +844,7 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
blk->free = 1;
|
mblk_free(blk) = 1;
|
||||||
attach_to_freelist(xma, (hawk_xma_fblk_t*)blk);
|
attach_to_freelist(xma, (hawk_xma_fblk_t*)blk);
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
@ -835,7 +859,7 @@ void hawk_xma_free (hawk_xma_t* xma, void* b)
|
|||||||
void hawk_xma_dump (hawk_xma_t* xma, hawk_xma_dumper_t dumper, void* ctx)
|
void hawk_xma_dump (hawk_xma_t* xma, hawk_xma_dumper_t dumper, void* ctx)
|
||||||
{
|
{
|
||||||
hawk_xma_mblk_t* tmp;
|
hawk_xma_mblk_t* tmp;
|
||||||
hawk_oow_t fsum, asum;
|
hawk_oow_t fsum, asum, xfi;
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
hawk_oow_t isum;
|
hawk_oow_t isum;
|
||||||
#endif
|
#endif
|
||||||
@ -859,6 +883,19 @@ void hawk_xma_dump (hawk_xma_t* xma, hawk_xma_dumper_t dumper, void* ctx)
|
|||||||
else asum += tmp->size;
|
else asum += tmp->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dumper(ctx, "== free list ==\n");
|
||||||
|
for (xfi = 0; xfi <= XFIMAX(xma); xfi++)
|
||||||
|
{
|
||||||
|
if (xma->xfree[xfi])
|
||||||
|
{
|
||||||
|
hawk_xma_fblk_t* f;
|
||||||
|
for (f = xma->xfree[xfi]; f; f = f->free_next)
|
||||||
|
{
|
||||||
|
dumper(ctx, " xfi %d fblk %p size %lu\n", xfi, f, (unsigned long)f->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||||
isum = (xma->stat.nfree + xma->stat.nused) * MBLKHDRSIZE;
|
isum = (xma->stat.nfree + xma->stat.nused) * MBLKHDRSIZE;
|
||||||
#endif
|
#endif
|
||||||
|
34
t/t-008.c
34
t/t-008.c
@ -5,32 +5,40 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "tap.h"
|
#include "tap.h"
|
||||||
|
|
||||||
#define NUM_ITERATIONS 1000000
|
#define NUM_ITERATIONS 10000
|
||||||
#define MIN_ALLOC_SIZE 16
|
#define MIN_ALLOC_SIZE 16
|
||||||
#define MAX_ALLOC_SIZE 1024
|
#define MAX_ALLOC_SIZE 1024
|
||||||
|
|
||||||
#define OK_X(test) OK(test, #test)
|
#define OK_X(test) OK(test, #test)
|
||||||
|
|
||||||
static size_t random_size()
|
static size_t random_size(hawk_oow_t max_alloc_size)
|
||||||
{
|
{
|
||||||
return MIN_ALLOC_SIZE + rand() % (MAX_ALLOC_SIZE - MIN_ALLOC_SIZE + 1);
|
return MIN_ALLOC_SIZE + rand() % (max_alloc_size - MIN_ALLOC_SIZE + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int test_bad = 0;
|
int test_bad = 0;
|
||||||
hawk_mmgr_t xma_mmgr;
|
hawk_mmgr_t xma_mmgr;
|
||||||
|
hawk_oow_t num_iterations = NUM_ITERATIONS;
|
||||||
|
hawk_oow_t max_alloc_size = MAX_ALLOC_SIZE;
|
||||||
|
|
||||||
clock_t start_time, end_time;
|
clock_t start_time, end_time;
|
||||||
double malloc_time = 0.0, free_time = 0.0;
|
double malloc_time = 0.0, free_time = 0.0;
|
||||||
void **ptr_array;
|
void **ptr_array;
|
||||||
|
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
num_iterations = strtoul(argv[1], NULL, 10);
|
||||||
|
max_alloc_size = strtoul(argv[2], NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
no_plan();
|
no_plan();
|
||||||
hawk_init_xma_mmgr(&xma_mmgr, NUM_ITERATIONS * MAX_ALLOC_SIZE);
|
hawk_init_xma_mmgr(&xma_mmgr, num_iterations * max_alloc_size);
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
ptr_array = malloc(NUM_ITERATIONS * sizeof(void *));
|
ptr_array = malloc(num_iterations * sizeof(void *));
|
||||||
OK_X (ptr_array != NULL);
|
OK_X (ptr_array != NULL);
|
||||||
if (!ptr_array) {
|
if (!ptr_array) {
|
||||||
fprintf(stderr, "malloc failed for pointer array\n");
|
fprintf(stderr, "malloc failed for pointer array\n");
|
||||||
@ -38,8 +46,8 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
start_time = clock();
|
start_time = clock();
|
||||||
for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
|
for (size_t i = 0; i < num_iterations; ++i) {
|
||||||
size_t size = random_size();
|
size_t size = random_size(max_alloc_size);
|
||||||
/*ptr_array[i] = malloc(size);*/
|
/*ptr_array[i] = malloc(size);*/
|
||||||
ptr_array[i] = HAWK_MMGR_ALLOC(&xma_mmgr, size);
|
ptr_array[i] = HAWK_MMGR_ALLOC(&xma_mmgr, size);
|
||||||
if (!ptr_array[i]) {
|
if (!ptr_array[i]) {
|
||||||
@ -56,7 +64,7 @@ int main()
|
|||||||
malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;
|
malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
start_time = clock();
|
start_time = clock();
|
||||||
for (size_t i = 0; i < NUM_ITERATIONS; ++i) {
|
for (size_t i = 0; i < num_iterations; ++i) {
|
||||||
/*free(ptr_array[i]);*/
|
/*free(ptr_array[i]);*/
|
||||||
HAWK_MMGR_FREE(&xma_mmgr, ptr_array[i]);
|
HAWK_MMGR_FREE(&xma_mmgr, ptr_array[i]);
|
||||||
}
|
}
|
||||||
@ -65,12 +73,14 @@ int main()
|
|||||||
|
|
||||||
free(ptr_array);
|
free(ptr_array);
|
||||||
|
|
||||||
printf("Performed %d allocations and frees\n", NUM_ITERATIONS);
|
printf("Performed %lu allocations and frees - min alloc size %lu max_alloc_size %lu\n",
|
||||||
|
(unsigned long)num_iterations, (unsigned long)MIN_ALLOC_SIZE, (unsigned long)max_alloc_size);
|
||||||
printf("Total malloc time: %.6f seconds\n", malloc_time);
|
printf("Total malloc time: %.6f seconds\n", malloc_time);
|
||||||
printf("Total free time : %.6f seconds\n", free_time);
|
printf("Total free time : %.6f seconds\n", free_time);
|
||||||
printf("Average malloc time: %.9f seconds\n", malloc_time / NUM_ITERATIONS);
|
printf("Average malloc time: %.9f seconds\n", malloc_time / num_iterations);
|
||||||
printf("Average free time : %.9f seconds\n", free_time / NUM_ITERATIONS);
|
printf("Average free time : %.9f seconds\n", free_time / num_iterations);
|
||||||
|
|
||||||
|
hawk_fini_xma_mmgr(&xma_mmgr);
|
||||||
return exit_status();
|
return exit_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
t/t-009.c
125
t/t-009.c
@ -5,8 +5,8 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "tap.h"
|
#include "tap.h"
|
||||||
|
|
||||||
#define NUM_OPERATIONS 1000000
|
#define NUM_ITERATIONS 20000
|
||||||
#define MAX_ALLOCATIONS 10000
|
#define MAX_ALLOC_ACTIVE 1000
|
||||||
#define MIN_ALLOC_SIZE 16
|
#define MIN_ALLOC_SIZE 16
|
||||||
#define MAX_ALLOC_SIZE 1024
|
#define MAX_ALLOC_SIZE 1024
|
||||||
|
|
||||||
@ -27,34 +27,129 @@ static void print_xma (void* ctx, const hawk_bch_t* fmt, ...)
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t random_size()
|
static size_t random_size(hawk_oow_t max_alloc_size)
|
||||||
{
|
{
|
||||||
return MIN_ALLOC_SIZE + rand() % (MAX_ALLOC_SIZE - MIN_ALLOC_SIZE + 1);
|
return MIN_ALLOC_SIZE + rand() % (max_alloc_size - MIN_ALLOC_SIZE + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
static void test1(hawk_mmgr_t* mmgr)
|
||||||
|
{
|
||||||
|
void* x1, * x2, * x3;
|
||||||
|
|
||||||
|
x1 = HAWK_MMGR_ALLOC(mmgr, 416);
|
||||||
|
OK_X (x1 != HAWK_NULL);
|
||||||
|
x2 = HAWK_MMGR_ALLOC(mmgr, 688);
|
||||||
|
OK_X (x2 != HAWK_NULL);
|
||||||
|
|
||||||
|
HAWK_MMGR_FREE(mmgr, x1);
|
||||||
|
HAWK_MMGR_FREE(mmgr, x2);
|
||||||
|
x3 = HAWK_MMGR_ALLOC(mmgr, 144);
|
||||||
|
OK_X (x2 != HAWK_NULL);
|
||||||
|
|
||||||
|
HAWK_MMGR_FREE(mmgr, x3);
|
||||||
|
/*hawk_xma_dump(mmgr.ctx, print_xma, HAWK_NULL);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test2(hawk_mmgr_t* mmgr)
|
||||||
|
{
|
||||||
|
int x[] =
|
||||||
|
{
|
||||||
|
960, 688, -688, -960, 560, 32, -560, -32, 336, 624, -624, -336, 672, -672, 304, -304, 992, -992, 608, -608,
|
||||||
|
576, 304, 256, -304, -256, 416,
|
||||||
|
};
|
||||||
|
int i, j;
|
||||||
|
int count;
|
||||||
|
void *p[100];
|
||||||
|
int sz[100];
|
||||||
|
int test2_bad = 0;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
for (i = 0; i < HAWK_COUNTOF(x); i++)
|
||||||
|
{
|
||||||
|
if (x[i] > 0)
|
||||||
|
{
|
||||||
|
p[count] = HAWK_MMGR_ALLOC(mmgr, x[i]);
|
||||||
|
if (!p[count])
|
||||||
|
{
|
||||||
|
test2_bad = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sz[count] = x[i];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else if (x[i] < 0)
|
||||||
|
{
|
||||||
|
for (j = 0; j < count; j++)
|
||||||
|
{
|
||||||
|
if (sz[j] == -x[i])
|
||||||
|
{
|
||||||
|
HAWK_MMGR_FREE(mmgr, p[j]);
|
||||||
|
count--;
|
||||||
|
p[j] = p[count];
|
||||||
|
sz[j] = sz[count];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*hawk_xma_dump(mmgr->ctx, print_xma, HAWK_NULL);*/
|
||||||
|
|
||||||
|
OK_X(test2_bad == 0);
|
||||||
|
for (j = 0; j < count; j++) HAWK_MMGR_FREE(mmgr, p[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int test_bad = 0;
|
int test_bad = 0;
|
||||||
hawk_mmgr_t xma_mmgr;
|
hawk_mmgr_t xma_mmgr;
|
||||||
|
hawk_oow_t max_alloc_size = MAX_ALLOC_SIZE;
|
||||||
|
hawk_oow_t num_iterations = NUM_ITERATIONS;
|
||||||
|
hawk_oow_t max_alloc_active = MAX_ALLOC_ACTIVE;
|
||||||
|
hawk_oow_t pool_size = 1000000;
|
||||||
|
|
||||||
Allocation allocations[MAX_ALLOCATIONS] = {0}; /* pool of active allocations */
|
Allocation* allocations; /* pool of active allocations */
|
||||||
size_t num_active = 0;
|
size_t num_active = 0;
|
||||||
|
|
||||||
clock_t start_time, end_time;
|
clock_t start_time, end_time;
|
||||||
double malloc_time = 0.0, free_time = 0.0;
|
double malloc_time = 0.0, free_time = 0.0;
|
||||||
|
|
||||||
|
if (argc >= 5)
|
||||||
|
{
|
||||||
|
num_iterations = strtoul(argv[1], NULL, 10);
|
||||||
|
max_alloc_size = strtoul(argv[2], NULL, 10);
|
||||||
|
max_alloc_active = strtoul(argv[3], NULL, 10);
|
||||||
|
pool_size = strtoul(argv[4], NULL, 10);
|
||||||
|
}
|
||||||
|
else if (argc != 1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Usage: %s num_iterations max_alloc_size max_alloc_active pool_size\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
no_plan();
|
no_plan();
|
||||||
hawk_init_xma_mmgr(&xma_mmgr, 20000000);
|
hawk_init_xma_mmgr(&xma_mmgr, pool_size);
|
||||||
|
|
||||||
|
allocations = HAWK_MMGR_ALLOC(&xma_mmgr, max_alloc_active * sizeof(*allocations));
|
||||||
|
if (!allocations)
|
||||||
|
{
|
||||||
|
bail_out("base allocation failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------- */
|
||||||
|
test1(&xma_mmgr);
|
||||||
|
test2(&xma_mmgr);
|
||||||
|
|
||||||
|
/* ------------------------------- */
|
||||||
|
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
start_time = clock();
|
start_time = clock();
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_OPERATIONS; ++i)
|
for (size_t i = 0; i < num_iterations; ++i)
|
||||||
{
|
{
|
||||||
int do_alloc = (num_active == 0) || (rand() % 2 == 0 && num_active < MAX_ALLOCATIONS);
|
int do_alloc = (num_active == 0) || (rand() % 2 == 0 && num_active < max_alloc_active);
|
||||||
|
|
||||||
if (do_alloc) {
|
if (do_alloc) {
|
||||||
size_t size = random_size();
|
size_t size = random_size(max_alloc_size);
|
||||||
/*void *ptr = malloc(size);*/
|
/*void *ptr = malloc(size);*/
|
||||||
void *ptr = HAWK_MMGR_ALLOC(&xma_mmgr, size);
|
void *ptr = HAWK_MMGR_ALLOC(&xma_mmgr, size);
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
@ -67,7 +162,7 @@ int main()
|
|||||||
allocations[num_active].size = size;
|
allocations[num_active].size = size;
|
||||||
++num_active;
|
++num_active;
|
||||||
} else {
|
} else {
|
||||||
/* Free a random active allocation */
|
/* free a random active allocation */
|
||||||
size_t index = rand() % num_active;
|
size_t index = rand() % num_active;
|
||||||
void *ptr_to_free = allocations[index].ptr;
|
void *ptr_to_free = allocations[index].ptr;
|
||||||
|
|
||||||
@ -77,7 +172,7 @@ int main()
|
|||||||
clock_t t2 = clock();
|
clock_t t2 = clock();
|
||||||
free_time += (double)(t2 - t1) / CLOCKS_PER_SEC;
|
free_time += (double)(t2 - t1) / CLOCKS_PER_SEC;
|
||||||
|
|
||||||
/* Replace with last active allocation */
|
/* replace with last active allocation */
|
||||||
allocations[index] = allocations[num_active - 1];
|
allocations[index] = allocations[num_active - 1];
|
||||||
--num_active;
|
--num_active;
|
||||||
}
|
}
|
||||||
@ -97,11 +192,13 @@ int main()
|
|||||||
|
|
||||||
malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC - free_time;
|
malloc_time = (double)(end_time - start_time) / CLOCKS_PER_SEC - free_time;
|
||||||
|
|
||||||
printf("Performed %d interleaved malloc/free operations\n", NUM_OPERATIONS);
|
printf("Performed %d interleaved malloc/free operations\n", num_iterations);
|
||||||
printf("Total malloc time (estimated): %.6f seconds\n", malloc_time);
|
printf("Total malloc time (estimated): %.6f seconds\n", malloc_time);
|
||||||
printf("Total free time : %.6f seconds\n", free_time);
|
printf("Total free time : %.6f seconds\n", free_time);
|
||||||
printf("Average time per operation : %.9f seconds\n", (malloc_time + free_time) / NUM_OPERATIONS);
|
printf("Average time per operation : %.9f seconds\n", (malloc_time + free_time) / num_iterations);
|
||||||
|
|
||||||
|
HAWK_MMGR_FREE(&xma_mmgr, allocations);
|
||||||
|
hawk_fini_xma_mmgr(&xma_mmgr);
|
||||||
return exit_status();
|
return exit_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user