added realloc to xma

This commit is contained in:
hyung-hwan 2010-07-31 07:24:19 +00:00
parent a1965a6544
commit 4ef1730e71
10 changed files with 404 additions and 92 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c 337 2010-07-28 13:27:03Z hyunghwan.chung $ * $Id: awk.c 338 2010-07-30 13:24:19Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -700,7 +700,7 @@ qse_htb_walk_t add_global (qse_htb_t* map, qse_htb_pair_t* pair, void* arg)
static qse_mmgr_t xma_mmgr = static qse_mmgr_t xma_mmgr =
{ {
qse_xma_alloc, qse_xma_alloc,
QSE_NULL, qse_xma_realloc,
qse_xma_free, qse_xma_free,
QSE_NULL QSE_NULL
}; };

12
qse/configure vendored
View File

@ -17397,15 +17397,15 @@ fi
if test "$enable_debug_is" = "yes" if test "$enable_debug_is" = "yes"
then then
CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG" CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"
OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG" OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"
CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG" CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"
BUILD_MODE="debug" BUILD_MODE="debug"
else else
CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG" CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"
OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG" OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"
CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG" CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"
BUILD_MODE="release" BUILD_MODE="release"
fi fi

View File

@ -201,14 +201,14 @@ AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug],
enable_debug_is=$enableval,enable_debug_is=no) enable_debug_is=$enableval,enable_debug_is=no)
if test "$enable_debug_is" = "yes" if test "$enable_debug_is" = "yes"
then then
[CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG"] [CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"]
[OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG"] [OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"]
[CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG"] [CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"]
AC_SUBST(BUILD_MODE, "debug") AC_SUBST(BUILD_MODE, "debug")
else else
[CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG"] [CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"]
[OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG"] [OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"]
[CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG"] [CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"]
AC_SUBST(BUILD_MODE, "release") AC_SUBST(BUILD_MODE, "release")
fi fi

View File

@ -24,6 +24,10 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
#ifdef QSE_BUILD_DEBUG
# define QSE_XMA_ENABLE_STAT
#endif
typedef struct qse_xma_t qse_xma_t; typedef struct qse_xma_t qse_xma_t;
typedef struct qse_xma_blk_t qse_xma_blk_t; typedef struct qse_xma_blk_t qse_xma_blk_t;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: macros.h 323 2010-04-05 12:50:01Z hyunghwan.chung $ * $Id: macros.h 338 2010-07-30 13:24:19Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -35,6 +35,23 @@
# define QSE_INLINE # define QSE_INLINE
#endif #endif
#if defined(__GNUC__)
# define QSE_INLINE_ALWAYS inline __attribute__((__always_inline__))
#elif defined(_MSC_VER) || (defined(__CC_ARM) || defined(__ARMCC__))
# define QSE_INLINE_ALWAYS __forceinline
#else
# define QSE_INLINE_ALWAYS QSE_INLINE
#endif
#if defined(__GNUC__)
# define QSE_INLINE_NEVER inline __attribute__((__noinline__))
#elif (defined(__CC_ARM) || defined(__ARMCC__))
# define QSE_INLINE_NEVER __declspec(noinline)
#else
# define QSE_INLINE_NEVER
#endif
/** /**
* The #QSE_NULL macro defines a special pointer value to indicate an error or * The #QSE_NULL macro defines a special pointer value to indicate an error or
* that it does not point to anything. * that it does not point to anything.

View File

@ -1,5 +1,5 @@
/* /*
* $Id: types.h 337 2010-07-28 13:27:03Z hyunghwan.chung $ * $Id: types.h 338 2010-07-30 13:24:19Z hyunghwan.chung $
* *
Copyright 2006-2009 Chung, Hyung-Hwan. Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -408,40 +408,39 @@ struct qse_cstr_t
}; };
typedef struct qse_cstr_t qse_cstr_t; typedef struct qse_cstr_t qse_cstr_t;
/**
* allocate a memory chunk of the size @a n.
* @return a pointer to a memory chunk on success, QSE_NULL on failure.
*/
typedef void* (*qse_mmgr_alloc_t) (void* udd, qse_size_t n);
/**
* resize a memory chunk pointed to by @a ptr to the size @a n.
* @return a pointer to a memory chunk on success, QSE_NULL on failure.
*/
typedef void* (*qse_mmgr_realloc_t) (void* udd, void* ptr, qse_size_t n);
/** /**
* The qse_mmgr_t type defines a set type of functions for memory management. * free a memory chunk pointed to by @a ptr.
*/
typedef void (*qse_mmgr_free_t) (void* udd, void* ptr);
/**
* The qse_mmgr_t type defines a set of functions for memory management.
* As the type is merely a structure, it is just used as a single container * As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data. * for memory management functions with a pointer to user-defined data.
* The user-defined \a data is passed to each memory management function * The user-defined data pointer @a udd is passed to each memory management
* whenever it is called. You can allocate, reallocate, and free a memory * function whenever it is called. You can allocate, reallocate, and free
* chunk. * a memory chunk.
* *
* For example, a qse_xxx_open() function accepts a pointer of the qse_mmgr_t * * For example, a qse_xxx_open() function accepts a pointer of the qse_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object. * type and the xxx object uses it to manage dynamic data within the object.
*/ */
struct qse_mmgr_t struct qse_mmgr_t
{ {
/** qse_mmgr_alloc_t alloc; /**< allocation function */
* allocate a memory chunk of the size \a n. qse_mmgr_realloc_t realloc; /**< resizing function */
* @return a pointer to a memory chunk on success, QSE_NULL on failure. qse_mmgr_free_t free; /**< disposal function */
*/ void* udd; /**< user-defined data pointer */
void* (*alloc) (void* udd, qse_size_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* @return a pointer to a memory chunk on success, QSE_NULL on failure.
*/
void* (*realloc) (void* udd, void* ptr, qse_size_t n);
/**
* frees a memory chunk pointed to by \a ptr.
*/
void (*free) (void* udd, void* ptr);
/**
* a pointer to user-defined data passed as the first parameter to
* alloc(), realloc(), and free().
*/
void* udd;
}; };
typedef struct qse_mmgr_t qse_mmgr_t; typedef struct qse_mmgr_t qse_mmgr_t;
/******/
#endif #endif

View File

@ -23,6 +23,7 @@
#define ALIGN QSE_SIZEOF(qse_size_t) #define ALIGN QSE_SIZEOF(qse_size_t)
#define HDRSIZE QSE_SIZEOF(qse_xma_blk_t) #define HDRSIZE QSE_SIZEOF(qse_xma_blk_t)
#define MINBLKLEN (HDRSIZE + ALIGN)
#define SYS_TO_USR(_) (((qse_xma_blk_t*)_) + 1) #define SYS_TO_USR(_) (((qse_xma_blk_t*)_) + 1)
#define USR_TO_SYS(_) (((qse_xma_blk_t*)_) - 1) #define USR_TO_SYS(_) (((qse_xma_blk_t*)_) - 1)
@ -34,9 +35,6 @@
*/ */
#define FIXED QSE_XMA_FIXED #define FIXED QSE_XMA_FIXED
#define XFIMAX(xma) (QSE_COUNTOF(xma->xfree)-1) #define XFIMAX(xma) (QSE_COUNTOF(xma->xfree)-1)
#define _XFI(size) (((size) / ALIGN) - 1)
#define _XFI_LARGE(xma,size) (szlog2(size) - (xma)->bdec + FIXED)
#define XFI(xma,size) ((_XFI(size) < FIXED)? _XFI(size): _XFI_LARGE(xma,size))
struct qse_xma_blk_t struct qse_xma_blk_t
{ {
@ -58,7 +56,7 @@ struct qse_xma_blk_t
QSE_IMPLEMENT_COMMON_FUNCTIONS (xma) QSE_IMPLEMENT_COMMON_FUNCTIONS (xma)
static QSE_INLINE qse_size_t szlog2 (qse_size_t n) static QSE_INLINE_ALWAYS qse_size_t szlog2 (qse_size_t n)
{ {
/* /*
* 2**x = n; * 2**x = n;
@ -98,6 +96,14 @@ static QSE_INLINE qse_size_t szlog2 (qse_size_t n)
#undef BITS #undef BITS
} }
static QSE_INLINE_ALWAYS qse_size_t getxfi (qse_xma_t* xma, qse_size_t size)
{
qse_size_t xfi = ((size) / ALIGN) - 1;
if (xfi >= FIXED) xfi = szlog2(size) - (xma)->bdec + FIXED;
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
return xfi;
}
qse_xma_t* qse_xma_open (qse_mmgr_t* mmgr, qse_size_t ext, qse_size_t size) qse_xma_t* qse_xma_open (qse_mmgr_t* mmgr, qse_size_t ext, qse_size_t size)
{ {
qse_xma_t* xma; qse_xma_t* xma;
@ -135,8 +141,9 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t size)
qse_xma_blk_t* free; qse_xma_blk_t* free;
qse_size_t xfi; qse_size_t xfi;
size = ((size + ALIGN - 1) / ALIGN) * ALIGN;
/* adjust 'size' to be large enough to hold a single smallest block */ /* adjust 'size' to be large enough to hold a single smallest block */
if (size < HDRSIZE + ALIGN) size = HDRSIZE + ALIGN; if (size < MINBLKLEN) size = MINBLKLEN;
/* allocate a memory chunk to use for actual memory allocation */ /* allocate a memory chunk to use for actual memory allocation */
free = QSE_MMGR_ALLOC (mmgr, size); free = QSE_MMGR_ALLOC (mmgr, size);
@ -155,8 +162,7 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t size)
xma->bdec = szlog2(FIXED*ALIGN); /* precalculate the decrement value */ xma->bdec = szlog2(FIXED*ALIGN); /* precalculate the decrement value */
/* the entire chunk is a free block */ /* the entire chunk is a free block */
xfi = XFI(xma,free->size); xfi = getxfi(xma,free->size);
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
xma->xfree[xfi] = free; /* locate it at the right slot */ xma->xfree[xfi] = free; /* locate it at the right slot */
xma->head = free; /* store it for furture reference */ xma->head = free; /* store it for furture reference */
@ -179,8 +185,7 @@ void qse_xma_fini (qse_xma_t* xma)
static QSE_INLINE void attach_to_freelist (qse_xma_t* xma, qse_xma_blk_t* b) static QSE_INLINE void attach_to_freelist (qse_xma_t* xma, qse_xma_blk_t* b)
{ {
qse_size_t xfi = XFI(xma,b->size); qse_size_t xfi = getxfi(xma,b->size);
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
b->f.prev = QSE_NULL; b->f.prev = QSE_NULL;
b->f.next = xma->xfree[xfi]; b->f.next = xma->xfree[xfi];
@ -201,9 +206,7 @@ static QSE_INLINE void detach_from_freelist (qse_xma_t* xma, qse_xma_blk_t* b)
} }
else else
{ {
qse_size_t xfi = XFI(xma,b->size); qse_size_t xfi = getxfi(xma,b->size);
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
QSE_ASSERT (b == xma->xfree[xfi]); QSE_ASSERT (b == xma->xfree[xfi]);
xma->xfree[xfi] = n; xma->xfree[xfi] = n;
} }
@ -222,7 +225,7 @@ static qse_xma_blk_t* alloc_from_freelist (
detach_from_freelist (xma, free); detach_from_freelist (xma, free);
qse_size_t rem = free->size - size; qse_size_t rem = free->size - size;
if (rem > HDRSIZE) if (rem >= MINBLKLEN)
{ {
qse_xma_blk_t* tmp; qse_xma_blk_t* tmp;
@ -292,8 +295,7 @@ void* qse_xma_alloc (qse_xma_t* xma, qse_size_t size)
size = ((size + ALIGN - 1) / ALIGN) * ALIGN; size = ((size + ALIGN - 1) / ALIGN) * ALIGN;
QSE_ASSERT (size >= ALIGN); QSE_ASSERT (size >= ALIGN);
xfi = XFI(xma,size); xfi = getxfi(xma,size);
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
/*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])
@ -354,10 +356,205 @@ void* qse_xma_alloc (qse_xma_t* xma, qse_size_t size)
return SYS_TO_USR(free); return SYS_TO_USR(free);
} }
static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size)
{
qse_xma_blk_t* blk = USR_TO_SYS(b);
if (size > blk->size)
{
qse_size_t req = size - blk->size;
qse_xma_blk_t* n;
qse_size_t rem;
n = blk->b.next;
if (!n || !n->avail || req > n->size) return QSE_NULL;
/* merge the current block with the next block
* if it is available */
detach_from_freelist (xma, n);
rem = (HDRSIZE + n->size) - req;
if (rem >= MINBLKLEN)
{
qse_xma_blk_t* tmp;
/* store n->b.next in case 'tmp' begins somewhere
* in the header part of n */
qse_xma_blk_t* nn = n->b.next;
tmp = (qse_xma_blk_t*)(((qse_byte_t*)n) + req);
tmp->avail = 1;
tmp->size = rem - HDRSIZE;
attach_to_freelist (xma, tmp);
blk->size += req;
tmp->b.next = nn;
if (nn) nn->b.prev = tmp;
blk->b.next = tmp;
tmp->b.prev = blk;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.alloc += req;
xma->stat.avail -= req; /* req + HDRSIZE(tmp) - HDRSIZE(n) */
#endif
}
else
{
blk->size += HDRSIZE + n->size;
blk->b.next = n->b.next;
if (n->b.next) n->b.next->b.prev = blk;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.nfree--;
xma->stat.alloc += HDRSIZE + n->size;
xma->stat.avail -= n->size;
#endif
}
#if 0
qse_size_t total = 0;
qse_xma_blk_t* x = QSE_NULL;
/* find continuous blocks available to accomodate
* additional space required */
for (n = blk->b.next; n && n->avail; n = n->b.next)
{
total += n->size + HDRSIZE;
if (req <= total)
{
x = n;
break;
}
n = n->b.next;
}
if (!x)
{
/* no such blocks. return failure */
return QSE_NULL;
}
for (n = blk->b.next; n != x; n = n->b.next)
{
detach_from_freelist (xma, n);
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.nfree--;
#endif
}
detach_from_freelist (xma, x);
rem = total - req;
if (rem >= MINBLKLEN)
{
qse_xma_blk_t* tmp;
tmp = (qse_xma_blk_t*)(((qse_byte_t*)(blk->b.next + 1)) + req);
tmp->avail = 1;
tmp->size = rem - HDRSIZE;
attach_to_freelist (xma, tmp);
blk->size += req;
tmp->b.next = x->b.next;
if (x->b.next) x->b.next->b.prev = tmp;
blk->b.next = tmp;
tmp->b.prev = blk;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.alloc += req;
xma->stat.avail -= req + HDRSIZE;
#endif
}
else
{
blk->size += total;
blk->b.next = x->b.next;
if (x->b.next) x->b.next->b.prev = blk;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.nfree--;
xma->stat.alloc += total;
xma->stat.avail -= total;
#endif
}
#endif
}
else if (size < blk->size)
{
qse_size_t rem = blk->size - size;
if (rem >= MINBLKLEN)
{
qse_xma_blk_t* tmp;
/* the leftover is large enough to hold a block
* of minimum size. split the current block.
* let 'tmp' point to the leftover. */
tmp = (qse_xma_blk_t*)(((qse_byte_t*)(blk + 1)) + size);
tmp->avail = 1;
tmp->size = rem - HDRSIZE;
/* link 'tmp' to the block list */
tmp->b.next = blk->b.next;
tmp->b.prev = blk;
if (blk->b.next) blk->b.next->b.prev = tmp;
blk->b.next = tmp;
blk->size = size;
/* add 'tmp' to the free list */
attach_to_freelist (xma, tmp);
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
/* TODO: if the next block is free. need to merge tmp with that..... */
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.nfree++;
xma->stat.alloc -= rem;
xma->stat.avail += tmp->size;
#endif
}
}
return b;
}
void* qse_xma_realloc (qse_xma_t* xma, void* b, qse_size_t size) void* qse_xma_realloc (qse_xma_t* xma, void* b, qse_size_t size)
{ {
/* TODO */ void* n;
return QSE_NULL;
if (b == QSE_NULL)
{
/* 'realloc' with NULL is the same as 'alloc' */
n = qse_xma_alloc (xma, size);
}
else
{
/* try reallocation by merging the adjacent continuous blocks */
n = _realloc_merge (xma, b, size);
if (n == QSE_NULL)
{
/* reallocation by merging failed. fall back to the slow
* allocation-copy-free scheme */
n = qse_xma_alloc (xma, size);
if (n)
{
QSE_MEMCPY (n, b, size);
qse_xma_free (xma, b);
}
}
}
return n;
} }
void qse_xma_free (qse_xma_t* xma, void* b) void qse_xma_free (qse_xma_t* xma, void* b)
@ -399,7 +596,8 @@ void qse_xma_free (qse_xma_t* xma, void* b)
qse_xma_blk_t* x = blk->b.prev; qse_xma_blk_t* x = blk->b.prev;
qse_xma_blk_t* y = blk->b.next; qse_xma_blk_t* y = blk->b.next;
qse_xma_blk_t* z = y->b.next; qse_xma_blk_t* z = y->b.next;
qse_size_t bs = blk->size + HDRSIZE + y->size + HDRSIZE; qse_size_t ns = HDRSIZE + blk->size + HDRSIZE;
qse_size_t bs = ns + y->size;
detach_from_freelist (xma, x); detach_from_freelist (xma, x);
detach_from_freelist (xma, y); detach_from_freelist (xma, y);
@ -412,7 +610,7 @@ void qse_xma_free (qse_xma_t* xma, void* b)
#ifdef QSE_XMA_ENABLE_STAT #ifdef QSE_XMA_ENABLE_STAT
xma->stat.nfree--; xma->stat.nfree--;
xma->stat.avail += bs; xma->stat.avail += ns;
#endif #endif
} }
else if (blk->b.next && blk->b.next->avail) else if (blk->b.next && blk->b.next->avail)
@ -440,7 +638,10 @@ void qse_xma_free (qse_xma_t* xma, void* b)
*/ */
qse_xma_blk_t* x = blk->b.next; qse_xma_blk_t* x = blk->b.next;
qse_xma_blk_t* y = x->b.next; qse_xma_blk_t* y = x->b.next;
qse_size_t bs = x->size + HDRSIZE;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.avail += blk->size + HDRSIZE;
#endif
/* detach x from the free list */ /* detach x from the free list */
detach_from_freelist (xma, x); detach_from_freelist (xma, x);
@ -448,7 +649,7 @@ void qse_xma_free (qse_xma_t* xma, void* b)
/* update the block availability */ /* update the block availability */
blk->avail = 1; blk->avail = 1;
/* update the block size. HDRSIZE for the header space in x */ /* update the block size. HDRSIZE for the header space in x */
blk->size += bs; blk->size += HDRSIZE + x->size;
/* update the backward link of Y */ /* update the backward link of Y */
if (y) y->b.prev = blk; if (y) y->b.prev = blk;
@ -458,9 +659,6 @@ void qse_xma_free (qse_xma_t* xma, void* b)
/* attach blk to the free list */ /* attach blk to the free list */
attach_to_freelist (xma, blk); attach_to_freelist (xma, blk);
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.avail += bs;
#endif
} }
else if (blk->b.prev && blk->b.prev->avail) else if (blk->b.prev && blk->b.prev->avail)
{ {
@ -488,19 +686,18 @@ void qse_xma_free (qse_xma_t* xma, void* b)
*/ */
qse_xma_blk_t* x = blk->b.prev; qse_xma_blk_t* x = blk->b.prev;
qse_xma_blk_t* y = blk->b.next; qse_xma_blk_t* y = blk->b.next;
qse_size_t bs = blk->size + HDRSIZE;
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.avail += HDRSIZE + blk->size;
#endif
detach_from_freelist (xma, x); detach_from_freelist (xma, x);
x->size += bs; x->size += HDRSIZE + blk->size;
x->b.next = y; x->b.next = y;
if (y) y->b.prev = x; if (y) y->b.prev = x;
attach_to_freelist (xma, x); attach_to_freelist (xma, x);
#ifdef QSE_XMA_ENABLE_STAT
xma->stat.avail += bs;
#endif
} }
else else
{ {
@ -514,36 +711,45 @@ void qse_xma_free (qse_xma_t* xma, void* b)
} }
} }
#if 0
void qse_xma_dump (qse_xma_t* xma) void qse_xma_dump (qse_xma_t* xma)
{ {
qse_xma_blk_t* tmp; qse_xma_blk_t* tmp;
unsigned long long fsum, asum, isum; unsigned long long fsum, asum;
#ifdef QSE_XMA_ENABLE_STAT
unsigned long long isum;
#endif
printf ("<MMP DUMP>\n"); qse_printf (QSE_T("<XMA DUMP>\n"));
printf ("== statistics ==\n"); #ifdef QSE_XMA_ENABLE_STAT
printf ("total = %llu\n", (unsigned long long)xma->stat.total); qse_printf (QSE_T("== statistics ==\n"));
printf ("alloc = %llu\n", (unsigned long long)xma->stat.alloc); qse_printf (QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total);
printf ("avail = %llu\n", (unsigned long long)xma->stat.avail); qse_printf (QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc);
qse_printf (QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail);
#endif
printf ("== blocks ==\n"); qse_printf (QSE_T("== blocks ==\n"));
printf (" size avail address\n"); qse_printf (QSE_T(" size avail address\n"));
for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next) for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next)
{ {
printf (" %-18llu %-5d %p\n", (unsigned long long)tmp->size, tmp->avail, tmp); qse_printf (QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp);
if (tmp->avail) fsum += tmp->size; if (tmp->avail) fsum += tmp->size;
else asum += tmp->size; else asum += tmp->size;
} }
#ifdef QSE_XMA_ENABLE_STAT
isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE; isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE;
#endif
printf ("---------------------------------------\n"); qse_printf (QSE_T("---------------------------------------\n"));
printf ("Allocated blocks: %18llu bytes\n", asum); qse_printf (QSE_T("Allocated blocks: %18llu bytes\n"), asum);
printf ("Available blocks: %18llu bytes\n", fsum); qse_printf (QSE_T("Available blocks: %18llu bytes\n"), fsum);
printf ("Internal use : %18llu bytes\n", isum); #ifdef QSE_XMA_ENABLE_STAT
printf ("Total : %18llu bytes\n", asum + fsum + isum); qse_printf (QSE_T("Internal use : %18llu bytes\n"), isum);
qse_printf (QSE_T("Total : %18llu bytes\n"), asum + fsum + isum);
#endif
} }
#if 0
int main () int main ()
{ {
int i; int i;

View File

@ -1,10 +1,11 @@
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
bin_PROGRAMS = chr str sll lda htb rbt fio pio sio time main rex01 bin_PROGRAMS = xma chr str sll lda htb rbt fio pio sio time main rex01
LDFLAGS = -L../../lib/cmn LDFLAGS = -L../../lib/cmn
LDADD = -lqsecmn LDADD = -lqsecmn
xma_SOURCES = xma.c
chr_SOURCES = chr.c chr_SOURCES = chr.c
str_SOURCES = str.c str_SOURCES = str.c
sll_SOURCES = sll.c sll_SOURCES = sll.c

View File

@ -34,9 +34,10 @@ PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
bin_PROGRAMS = chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) lda$(EXEEXT) \ bin_PROGRAMS = xma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) \
htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) \ lda$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) \
sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT) pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) \
rex01$(EXEEXT)
subdir = samples/cmn subdir = samples/cmn
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -101,6 +102,10 @@ am_time_OBJECTS = time.$(OBJEXT)
time_OBJECTS = $(am_time_OBJECTS) time_OBJECTS = $(am_time_OBJECTS)
time_LDADD = $(LDADD) time_LDADD = $(LDADD)
time_DEPENDENCIES = time_DEPENDENCIES =
am_xma_OBJECTS = xma.$(OBJEXT)
xma_OBJECTS = $(am_xma_OBJECTS)
xma_LDADD = $(LDADD)
xma_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/qse
depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp
am__depfiles_maybe = depfiles am__depfiles_maybe = depfiles
@ -116,11 +121,12 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@ $(LDFLAGS) -o $@
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) $(lda_SOURCES) \ SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) $(lda_SOURCES) \
$(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \ $(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \
$(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) \
$(xma_SOURCES)
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) \ DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) \
$(lda_SOURCES) $(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) \ $(lda_SOURCES) $(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) \
$(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \
$(time_SOURCES) $(time_SOURCES) $(xma_SOURCES)
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@ -265,6 +271,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
LDADD = -lqsecmn LDADD = -lqsecmn
xma_SOURCES = xma.c
chr_SOURCES = chr.c chr_SOURCES = chr.c
str_SOURCES = str.c str_SOURCES = str.c
sll_SOURCES = sll.c sll_SOURCES = sll.c
@ -390,6 +397,9 @@ str$(EXEEXT): $(str_OBJECTS) $(str_DEPENDENCIES)
time$(EXEEXT): $(time_OBJECTS) $(time_DEPENDENCIES) time$(EXEEXT): $(time_OBJECTS) $(time_DEPENDENCIES)
@rm -f time$(EXEEXT) @rm -f time$(EXEEXT)
$(LINK) $(time_OBJECTS) $(time_LDADD) $(LIBS) $(LINK) $(time_OBJECTS) $(time_LDADD) $(LIBS)
xma$(EXEEXT): $(xma_OBJECTS) $(xma_DEPENDENCIES)
@rm -f xma$(EXEEXT)
$(LINK) $(xma_OBJECTS) $(xma_LDADD) $(LIBS)
mostlyclean-compile: mostlyclean-compile:
-rm -f *.$(OBJEXT) -rm -f *.$(OBJEXT)
@ -409,6 +419,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sll.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xma.Po@am__quote@
.c.o: .c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<

74
qse/samples/cmn/xma.c Normal file
View File

@ -0,0 +1,74 @@
#include <qse/cmn/xma.h>
#include <qse/cmn/stdio.h>
int main ()
{
int i;
void* ptr[100];
void* x;
qse_xma_t* xma = qse_xma_open (QSE_NULL, 0, 100000L);
if (xma == QSE_NULL)
{
qse_printf (QSE_T("cannot open xma\n"));
return -1;
}
ptr[0] = qse_xma_alloc (xma, 5000);
ptr[1] = qse_xma_alloc (xma, 1000);
ptr[2] = qse_xma_alloc (xma, 3000);
ptr[3] = qse_xma_alloc (xma, 1000);
qse_xma_dump (xma);
qse_xma_free (xma, ptr[0]);
qse_xma_free (xma, ptr[2]);
//qse_xma_free (xma, ptr[3]);
qse_xma_dump (xma);
qse_printf (QSE_T("===============================\n"));
qse_xma_realloc (xma, ptr[1], 500);
qse_xma_dump (xma);
#if 0
for (i = 0; i < 100; i++)
{
int sz = (i + 1) * 10;
/*int sz = 10240;*/
ptr[i] = qse_xma_alloc (xma, sz);
if (ptr[i] == QSE_NULL)
{
qse_printf (QSE_T("failed to alloc %d\n"), sz);
break;
}
qse_printf (QSE_T("%d %p\n"), sz, ptr[i]);
}
for (--i; i > 0; i-= 3)
{
if (i >= 0) qse_xma_free (xma, ptr[i]);
}
/*
qse_xma_free (xma, ptr[0]);
qse_xma_free (xma, ptr[1]);
qse_xma_free (xma, ptr[2]);
*/
{
void* x, * y;
qse_printf (QSE_T("%p\n"), qse_xma_alloc (xma, 5000));
qse_printf (QSE_T("%p\n"), qse_xma_alloc (xma, 1000));
qse_printf (QSE_T("%p\n"), (x = qse_xma_alloc (xma, 10)));
qse_printf (QSE_T("%p\n"), (y = qse_xma_alloc (xma, 40)));
if (x) qse_xma_free (xma, x);
if (y) qse_xma_free (xma, y);
qse_printf (QSE_T("%p\n"), (x = qse_xma_alloc (xma, 10)));
qse_printf (QSE_T("%p\n"), (y = qse_xma_alloc (xma, 40)));
}
qse_xma_dump (xma);
#endif
qse_xma_close (xma);
return 0;
}