From 4ef1730e71fe03ae7150c0804df0467d36a1944d Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 31 Jul 2010 07:24:19 +0000 Subject: [PATCH] added realloc to xma --- qse/cmd/awk/awk.c | 4 +- qse/configure | 12 +- qse/configure.ac | 12 +- qse/include/qse/cmn/xma.h | 4 + qse/include/qse/macros.h | 19 ++- qse/include/qse/types.h | 51 +++---- qse/lib/cmn/xma.c | 296 ++++++++++++++++++++++++++++++------ qse/samples/cmn/Makefile.am | 3 +- qse/samples/cmn/Makefile.in | 21 ++- qse/samples/cmn/xma.c | 74 +++++++++ 10 files changed, 404 insertions(+), 92 deletions(-) create mode 100644 qse/samples/cmn/xma.c diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 1bb116f7..f6aa7017 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -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. 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 = { qse_xma_alloc, - QSE_NULL, + qse_xma_realloc, qse_xma_free, QSE_NULL }; diff --git a/qse/configure b/qse/configure index e1b99305..d5c1ae1b 100755 --- a/qse/configure +++ b/qse/configure @@ -17397,15 +17397,15 @@ fi if test "$enable_debug_is" = "yes" then - CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG" - OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG" - CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG" + CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG" + OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG" + CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG" BUILD_MODE="debug" else - CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG" - OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG" - CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG" + CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE" + OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE" + CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE" BUILD_MODE="release" fi diff --git a/qse/configure.ac b/qse/configure.ac index d64214a7..7c81fc20 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -201,14 +201,14 @@ AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug], enable_debug_is=$enableval,enable_debug_is=no) if test "$enable_debug_is" = "yes" then - [CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG"] - [OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG"] - [CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG"] + [CFLAGS="$CFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"] + [OBJCFLAGS="$OBJCFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"] + [CXXFLAGS="$CXXFLAGS -g -D_DEBUG -UNDEBUG -DQSE_BUILD_DEBUG"] AC_SUBST(BUILD_MODE, "debug") else - [CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG"] - [OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG"] - [CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG"] + [CFLAGS="$CFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"] + [OBJCFLAGS="$OBJCFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"] + [CXXFLAGS="$CXXFLAGS -DNDEBUG -U_DEBUG -DQSE_BUILD_RELEASE"] AC_SUBST(BUILD_MODE, "release") fi diff --git a/qse/include/qse/cmn/xma.h b/qse/include/qse/cmn/xma.h index add9cf4b..f729ac6d 100644 --- a/qse/include/qse/cmn/xma.h +++ b/qse/include/qse/cmn/xma.h @@ -24,6 +24,10 @@ #include #include +#ifdef QSE_BUILD_DEBUG +# define QSE_XMA_ENABLE_STAT +#endif + typedef struct qse_xma_t qse_xma_t; typedef struct qse_xma_blk_t qse_xma_blk_t; diff --git a/qse/include/qse/macros.h b/qse/include/qse/macros.h index 5773a8a5..93af813e 100644 --- a/qse/include/qse/macros.h +++ b/qse/include/qse/macros.h @@ -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. This file is part of QSE. @@ -35,6 +35,23 @@ # define QSE_INLINE #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 * that it does not point to anything. diff --git a/qse/include/qse/types.h b/qse/include/qse/types.h index 77b72fc0..7662d813 100644 --- a/qse/include/qse/types.h +++ b/qse/include/qse/types.h @@ -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. This file is part of QSE. @@ -408,40 +408,39 @@ struct 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 * for memory management functions with a pointer to user-defined data. - * The user-defined \a data is passed to each memory management function - * whenever it is called. You can allocate, reallocate, and free a memory - * chunk. + * The user-defined data pointer @a udd is passed to each memory management + * function whenever it is called. You can allocate, reallocate, and free + * 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. */ struct qse_mmgr_t { - /** - * allocate a memory chunk of the size \a n. - * @return a pointer to a memory chunk on success, QSE_NULL on failure. - */ - 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; + qse_mmgr_alloc_t alloc; /**< allocation function */ + qse_mmgr_realloc_t realloc; /**< resizing function */ + qse_mmgr_free_t free; /**< disposal function */ + void* udd; /**< user-defined data pointer */ }; typedef struct qse_mmgr_t qse_mmgr_t; -/******/ #endif diff --git a/qse/lib/cmn/xma.c b/qse/lib/cmn/xma.c index 653e9ffe..e77083d1 100644 --- a/qse/lib/cmn/xma.c +++ b/qse/lib/cmn/xma.c @@ -23,6 +23,7 @@ #define ALIGN QSE_SIZEOF(qse_size_t) #define HDRSIZE QSE_SIZEOF(qse_xma_blk_t) +#define MINBLKLEN (HDRSIZE + ALIGN) #define SYS_TO_USR(_) (((qse_xma_blk_t*)_) + 1) #define USR_TO_SYS(_) (((qse_xma_blk_t*)_) - 1) @@ -34,9 +35,6 @@ */ #define FIXED QSE_XMA_FIXED #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 { @@ -58,7 +56,7 @@ struct qse_xma_blk_t 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; @@ -98,6 +96,14 @@ static QSE_INLINE qse_size_t szlog2 (qse_size_t n) #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* 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_size_t xfi; + size = ((size + ALIGN - 1) / ALIGN) * ALIGN; /* 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 */ 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 */ /* the entire chunk is a free block */ - xfi = XFI(xma,free->size); - if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma); + xfi = getxfi(xma,free->size); xma->xfree[xfi] = free; /* locate it at the right slot */ 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) { - qse_size_t xfi = XFI(xma,b->size); - if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma); + qse_size_t xfi = getxfi(xma,b->size); b->f.prev = QSE_NULL; 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 { - qse_size_t xfi = XFI(xma,b->size); - if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma); - + qse_size_t xfi = getxfi(xma,b->size); QSE_ASSERT (b == xma->xfree[xfi]); xma->xfree[xfi] = n; } @@ -222,7 +225,7 @@ static qse_xma_blk_t* alloc_from_freelist ( detach_from_freelist (xma, free); qse_size_t rem = free->size - size; - if (rem > HDRSIZE) + if (rem >= MINBLKLEN) { 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; QSE_ASSERT (size >= ALIGN); - xfi = XFI(xma,size); - if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma); + xfi = getxfi(xma,size); /*if (xfi < XFIMAX(xma) && 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); } +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) { - /* TODO */ - return QSE_NULL; + void* n; + + 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) @@ -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* y = blk->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, y); @@ -412,7 +610,7 @@ void qse_xma_free (qse_xma_t* xma, void* b) #ifdef QSE_XMA_ENABLE_STAT xma->stat.nfree--; - xma->stat.avail += bs; + xma->stat.avail += ns; #endif } 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* 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_from_freelist (xma, x); @@ -448,7 +649,7 @@ void qse_xma_free (qse_xma_t* xma, void* b) /* update the block availability */ blk->avail = 1; /* 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 */ 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_to_freelist (xma, blk); -#ifdef QSE_XMA_ENABLE_STAT - xma->stat.avail += bs; -#endif } 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* 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); - x->size += bs; + x->size += HDRSIZE + blk->size; x->b.next = y; if (y) y->b.prev = x; attach_to_freelist (xma, x); - -#ifdef QSE_XMA_ENABLE_STAT - xma->stat.avail += bs; -#endif } 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) { 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 ("\n"); - printf ("== statistics ==\n"); - printf ("total = %llu\n", (unsigned long long)xma->stat.total); - printf ("alloc = %llu\n", (unsigned long long)xma->stat.alloc); - printf ("avail = %llu\n", (unsigned long long)xma->stat.avail); + qse_printf (QSE_T("\n")); +#ifdef QSE_XMA_ENABLE_STAT + qse_printf (QSE_T("== statistics ==\n")); + qse_printf (QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total); + 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"); - printf (" size avail address\n"); + qse_printf (QSE_T("== blocks ==\n")); + qse_printf (QSE_T(" size avail address\n")); 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; else asum += tmp->size; } +#ifdef QSE_XMA_ENABLE_STAT isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE; +#endif - printf ("---------------------------------------\n"); - printf ("Allocated blocks: %18llu bytes\n", asum); - printf ("Available blocks: %18llu bytes\n", fsum); - printf ("Internal use : %18llu bytes\n", isum); - printf ("Total : %18llu bytes\n", asum + fsum + isum); + qse_printf (QSE_T("---------------------------------------\n")); + qse_printf (QSE_T("Allocated blocks: %18llu bytes\n"), asum); + qse_printf (QSE_T("Available blocks: %18llu bytes\n"), fsum); +#ifdef QSE_XMA_ENABLE_STAT + 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 i; diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index 63801497..70eeca05 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -1,10 +1,11 @@ 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 LDADD = -lqsecmn +xma_SOURCES = xma.c chr_SOURCES = chr.c str_SOURCES = str.c sll_SOURCES = sll.c diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index c96a953f..20ec9c5c 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -34,9 +34,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -bin_PROGRAMS = chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) lda$(EXEEXT) \ - htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) \ - sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT) +bin_PROGRAMS = xma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) \ + lda$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) \ + pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) \ + rex01$(EXEEXT) subdir = samples/cmn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -101,6 +102,10 @@ am_time_OBJECTS = time.$(OBJEXT) time_OBJECTS = $(am_time_OBJECTS) time_LDADD = $(LDADD) 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 depcomp = $(SHELL) $(top_srcdir)/ac/au/depcomp am__depfiles_maybe = depfiles @@ -116,11 +121,12 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) $(lda_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) \ $(lda_SOURCES) $(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) \ $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ - $(time_SOURCES) + $(time_SOURCES) $(xma_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -265,6 +271,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG LDADD = -lqsecmn +xma_SOURCES = xma.c chr_SOURCES = chr.c str_SOURCES = str.c sll_SOURCES = sll.c @@ -390,6 +397,9 @@ str$(EXEEXT): $(str_OBJECTS) $(str_DEPENDENCIES) time$(EXEEXT): $(time_OBJECTS) $(time_DEPENDENCIES) @rm -f time$(EXEEXT) $(LINK) $(time_OBJECTS) $(time_LDADD) $(LIBS) +xma$(EXEEXT): $(xma_OBJECTS) $(xma_DEPENDENCIES) + @rm -f xma$(EXEEXT) + $(LINK) $(xma_OBJECTS) $(xma_LDADD) $(LIBS) mostlyclean-compile: -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)/str.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: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/qse/samples/cmn/xma.c b/qse/samples/cmn/xma.c new file mode 100644 index 00000000..146fc000 --- /dev/null +++ b/qse/samples/cmn/xma.c @@ -0,0 +1,74 @@ +#include +#include + +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; +}