diff --git a/moo/lib/Makefile.am b/moo/lib/Makefile.am index 26fbaee..2de7abc 100644 --- a/moo/lib/Makefile.am +++ b/moo/lib/Makefile.am @@ -41,6 +41,7 @@ pkginclude_HEADERS = \ moo-opt.h \ moo-rbt.h \ moo-utl.h \ + moo-xma.h \ moo-std.h ################################################## @@ -61,7 +62,6 @@ libmoo_la_SOURCES = \ moo-rbt.h \ moo-utl.h \ moo-prv.h \ - moo-xma.h \ pack1.h \ unpack.h \ bigint.c \ diff --git a/moo/lib/Makefile.in b/moo/lib/Makefile.in index 0433c4a..7424243 100644 --- a/moo/lib/Makefile.in +++ b/moo/lib/Makefile.in @@ -440,6 +440,7 @@ pkginclude_HEADERS = \ moo-opt.h \ moo-rbt.h \ moo-utl.h \ + moo-xma.h \ moo-std.h pkglib_LTLIBRARIES = libmoo.la libmoox.la @@ -456,7 +457,6 @@ libmoo_la_SOURCES = \ moo-rbt.h \ moo-utl.h \ moo-prv.h \ - moo-xma.h \ pack1.h \ unpack.h \ bigint.c \ diff --git a/moo/lib/moo-xma.h b/moo/lib/moo-xma.h index 0cd3d40..a2107e2 100644 --- a/moo/lib/moo-xma.h +++ b/moo/lib/moo-xma.h @@ -91,6 +91,7 @@ struct moo_xma_t moo_uint8_t* start; /* zone beginning */ moo_uint8_t* end; /* zone end */ + int external; /** pointer array to free memory blocks */ moo_xma_fblk_t* xfree[MOO_XMA_FIXED + MOO_XMA_SIZE_BITS + 1]; @@ -134,8 +135,9 @@ extern "C" { */ MOO_EXPORT moo_xma_t* moo_xma_open ( moo_mmgr_t* mmgr, /**< memory manager */ - moo_oow_t xtnsize, /**< extension size in bytes */ - moo_oow_t zonesize /**< zone size in bytes */ + moo_oow_t xtnsize, /**< extension size in bytes */ + void* zoneptr, + moo_oow_t zonesize /**< zone size in bytes */ ); /** @@ -171,7 +173,8 @@ static MOO_INLINE void* moo_xma_getxtn (moo_xma_t* xma) { return (void*)(xma + 1 MOO_EXPORT int moo_xma_init ( moo_xma_t* xma, /**< memory allocator */ moo_mmgr_t* mmgr, /**< memory manager */ - moo_oow_t zonesize /**< zone size in bytes */ + void* zoneptr, /**< pointer to memory zone. if #MOO_NULL, a zone is auto-created */ + moo_oow_t zonesize /**< zone size in bytes */ ); /** diff --git a/moo/lib/xma.c b/moo/lib/xma.c index e892433..8592d1f 100644 --- a/moo/lib/xma.c +++ b/moo/lib/xma.c @@ -125,14 +125,14 @@ static MOO_INLINE moo_oow_t getxfi (moo_xma_t* xma, moo_oow_t size) return xfi; } -moo_xma_t* moo_xma_open (moo_mmgr_t* mmgr, moo_oow_t xtnsize, moo_oow_t zonesize) +moo_xma_t* moo_xma_open (moo_mmgr_t* mmgr, moo_oow_t xtnsize, void* zoneptr, moo_oow_t zonesize) { moo_xma_t* xma; xma = (moo_xma_t*)MOO_MMGR_ALLOC(mmgr, MOO_SIZEOF(*xma) + xtnsize); if (MOO_UNLIKELY(!xma)) return MOO_NULL; - if (moo_xma_init(xma, mmgr, zonesize) <= -1) + if (moo_xma_init(xma, mmgr, zoneptr, zonesize) <= -1) { MOO_MMGR_FREE (mmgr, xma); return MOO_NULL; @@ -148,20 +148,28 @@ void moo_xma_close (moo_xma_t* xma) MOO_MMGR_FREE (xma->_mmgr, xma); } -int moo_xma_init (moo_xma_t* xma, moo_mmgr_t* mmgr, moo_oow_t zonesize) +int moo_xma_init (moo_xma_t* xma, moo_mmgr_t* mmgr, void* zoneptr, moo_oow_t zonesize) { moo_xma_fblk_t* free; moo_oow_t xfi; - /* round 'zonesize' to be the multiples of ALIGN */ - zonesize = MOO_ALIGN_POW2(zonesize, ALIGN); + if (!zoneptr) + { + /* round 'zonesize' to be the multiples of ALIGN */ + zonesize = MOO_ALIGN_POW2(zonesize, ALIGN); - /* adjust 'zonesize' to be large enough to hold a single smallest block */ - if (zonesize < MINBLKLEN) zonesize = MINBLKLEN; + /* adjust 'zonesize' to be large enough to hold a single smallest block */ + if (zonesize < MINBLKLEN) zonesize = MINBLKLEN; - /* allocate a memory chunk to use for actual memory allocation */ - free = MOO_MMGR_ALLOC(mmgr, zonesize); - if (MOO_UNLIKELY(!free)) return -1; + zoneptr = MOO_MMGR_ALLOC(mmgr, zonesize); + if (MOO_UNLIKELY(!zoneptr)) return -1; + } + else + { + xma->external = 1; + } + + free = (moo_xma_fblk_t*)zoneptr; /* initialize the header part of the free chunk. the entire zone is a single free block */ free->prev_size = 0; @@ -201,7 +209,7 @@ void moo_xma_fini (moo_xma_t* xma) { /* the head must point to the free chunk allocated in init(). * let's deallocate it */ - MOO_MMGR_FREE (xma->_mmgr, xma->start); + if (!xma->external) MOO_MMGR_FREE (xma->_mmgr, xma->start); xma->start = MOO_NULL; xma->end = MOO_NULL; } @@ -650,7 +658,7 @@ void moo_xma_free (moo_xma_t* xma, void* b) /* attach blk to the free list */ attach_to_freelist (xma, (moo_xma_fblk_t*)blk); } - else if ((moo_uint8_t*)x < xma->end && x->avail) + else if ((moo_uint8_t*)x >= xma->start && x->avail) { /* * Merge the block with the previous block @@ -661,17 +669,12 @@ void moo_xma_free (moo_xma_t* xma, void* b) * +------------+------------+------------+ * | X | | Y | * +------------+------------+------------+ - * ^ | ^ | - * +------+ +------+ * - * - * +---------------------+ - * | v * +-------------------------+------------+ * | X | Y | * +-------------------------+------------+ - * ^ | - * +--------------------+ + * + * * */ #if defined(MOO_XMA_ENABLE_STAT) diff --git a/moo/t/t-005.c b/moo/t/t-005.c index 7805ede..37d2b26 100644 --- a/moo/t/t-005.c +++ b/moo/t/t-005.c @@ -41,7 +41,7 @@ int main () void* ptr1, * ptr2, * ptr3; - xma = moo_xma_open(&sys_mmgr, 0, 100000); + xma = moo_xma_open(&sys_mmgr, 0, MOO_NULL, 100000); ptr1 = moo_xma_alloc(xma, 1000);