added the xma memory manager
This commit is contained in:
parent
b17dfeea3c
commit
200f5f1d94
@ -28,6 +28,7 @@
|
||||
#include <hawk-utl.h>
|
||||
#include <hawk-fmt.h>
|
||||
#include <hawk-cli.h>
|
||||
#include <hawk-xma.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -1026,15 +1027,14 @@ static void print_hawk_rtx_error (hawk_rtx_t* rtx)
|
||||
);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void* xma_alloc (hawk_mmgr_t* mmgr, hawk_oow_t size)
|
||||
{
|
||||
return hawk_xma_alloc (mmgr->ctx, size);
|
||||
return hawk_xma_alloc(mmgr->ctx, size);
|
||||
}
|
||||
|
||||
static void* xma_realloc (hawk_mmgr_t* mmgr, void* ptr, hawk_oow_t size)
|
||||
{
|
||||
return hawk_xma_realloc (mmgr->ctx, ptr, size);
|
||||
return hawk_xma_realloc(mmgr->ctx, ptr, size);
|
||||
}
|
||||
|
||||
static void xma_free (hawk_mmgr_t* mmgr, void* ptr)
|
||||
@ -1050,7 +1050,6 @@ static hawk_mmgr_t xma_mmgr =
|
||||
HAWK_NULL
|
||||
};
|
||||
|
||||
|
||||
#if defined(HAWK_BUILD_DEBUG)
|
||||
static hawk_uintptr_t debug_mmgr_count = 0;
|
||||
static hawk_uintptr_t debug_mmgr_alloc_count = 0;
|
||||
@ -1098,8 +1097,6 @@ static hawk_mmgr_t debug_mmgr =
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
{
|
||||
hawk_t* hawk = HAWK_NULL;
|
||||
@ -1120,9 +1117,7 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
|
||||
/* TODO: change it to support multiple source files */
|
||||
hawk_parsestd_t psout;
|
||||
#if 0
|
||||
hawk_mmgr_t* mmgr = HAWK_MMGR_GETDFL();
|
||||
#endif
|
||||
hawk_mmgr_t* mmgr = hawk_get_sys_mmgr();
|
||||
|
||||
i = process_argv(argc, argv, &arg);
|
||||
if (i <= 0)
|
||||
@ -1140,7 +1135,6 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
psout.u.fileb.cmgr = arg.script_cmgr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(HAWK_BUILD_DEBUG)
|
||||
if (arg.failmalloc > 0)
|
||||
{
|
||||
@ -1151,7 +1145,7 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
#endif
|
||||
if (arg.memlimit > 0)
|
||||
{
|
||||
xma_mmgr.ctx = hawk_xma_open(HAWK_MMGR_GETDFL(), 0, arg.memlimit);
|
||||
xma_mmgr.ctx = hawk_xma_open(hawk_get_sys_mmgr(), 0, HAWK_NULL, arg.memlimit);
|
||||
if (xma_mmgr.ctx == HAWK_NULL)
|
||||
{
|
||||
print_error ("cannot open memory heap\n");
|
||||
@ -1159,9 +1153,8 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
}
|
||||
mmgr = &xma_mmgr;
|
||||
}
|
||||
#endif
|
||||
|
||||
hawk = hawk_openstd(0, HAWK_NULL);
|
||||
hawk = hawk_openstdwithmmgr(mmgr, 0, hawk_get_cmgr_by_id(HAWK_CMGR_UTF8), HAWK_NULL);
|
||||
if (HAWK_UNLIKELY(!hawk))
|
||||
{
|
||||
print_error ("cannot open hawk\n");
|
||||
@ -1252,7 +1245,7 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
|
||||
|
||||
if (apply_fs_and_gvs_to_rtx(rtx, &arg) <= -1)
|
||||
{
|
||||
print_hawk_error (hawk);
|
||||
print_hawk_rtx_error (hawk);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
@ -1300,9 +1293,7 @@ oops:
|
||||
if (rtx) hawk_rtx_close (rtx);
|
||||
if (hawk) hawk_close (hawk);
|
||||
|
||||
#if 0
|
||||
if (xma_mmgr.ctx) hawk_xma_close (xma_mmgr.ctx);
|
||||
#endif
|
||||
freearg (&arg);
|
||||
|
||||
#if defined(HAWK_BUILD_DEBUG)
|
||||
|
@ -50,7 +50,8 @@ pkginclude_HEADERS = \
|
||||
hawk-utl.h \
|
||||
hawk-std.h \
|
||||
hawk-tre.h \
|
||||
hawk-unpack.h
|
||||
hawk-unpack.h \
|
||||
hawk-xma.h
|
||||
|
||||
|
||||
##################################################
|
||||
@ -121,7 +122,8 @@ libhawk_la_SOURCES = \
|
||||
utl-sys.c \
|
||||
utl.c \
|
||||
val-prv.h \
|
||||
val.c
|
||||
val.c \
|
||||
xma.c
|
||||
|
||||
libhawk_la_SOURCES += \
|
||||
hawk-cli.h \
|
||||
|
@ -216,21 +216,22 @@ libhawk_sys_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
||||
am__libhawk_la_SOURCES_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \
|
||||
hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \
|
||||
hawk-map.h hawk-rbt.h hawk-pack1.h hawk-utl.h hawk-std.h \
|
||||
hawk-tre.h hawk-unpack.h Hawk.hpp HawkStd.hpp arr.c chr.c \
|
||||
dir.c ecs-imp.h ecs.c err-prv.h err.c err-sys.c fmt-imp.h \
|
||||
fmt.c fnc-prv.h fnc.c htb.c gem.c gem-skad.c gem-nwif.c \
|
||||
gem-nwif2.c hawk-prv.h hawk.c idmap-imp.h mb8.c misc-prv.h \
|
||||
misc.c parse-prv.h parse.c rbt.c rec.c rio-prv.h rio.c \
|
||||
run-prv.h run.c tre-prv.h tre-ast.c tre-ast.h tre-compile.c \
|
||||
tre-compile.h tre-match-bt.c tre-match-pa.c tre-match-ut.h \
|
||||
tre-mem.c tre-mem.h tre-parse.c tre-parse.h tre-stack.h \
|
||||
tre-stack.c tre.c tree-prv.h tree.c uch-prop.h uch-case.h \
|
||||
utf16.c utf8.c utl-ass.c utl-skad.c utl-skad.h utl-sort.c \
|
||||
utl-str.c utl-sys.c utl.c val-prv.h val.c hawk-cli.h \
|
||||
hawk-fio.h hawk-mtx.h hawk-pio.h hawk-sio.h hawk-tio.h \
|
||||
cli-imp.h cli.c fio.c mtx.c pio.c sio.c syscall.h tio.c \
|
||||
std-prv.h std.c Hawk.cpp HawkStd.cpp mod-hawk.c mod-hawk.h \
|
||||
mod-math.c mod-math.h mod-str.c mod-str.h mod-sys.c mod-sys.h
|
||||
hawk-tre.h hawk-unpack.h hawk-xma.h Hawk.hpp HawkStd.hpp arr.c \
|
||||
chr.c dir.c ecs-imp.h ecs.c err-prv.h err.c err-sys.c \
|
||||
fmt-imp.h fmt.c fnc-prv.h fnc.c htb.c gem.c gem-skad.c \
|
||||
gem-nwif.c gem-nwif2.c hawk-prv.h hawk.c idmap-imp.h mb8.c \
|
||||
misc-prv.h misc.c parse-prv.h parse.c rbt.c rec.c rio-prv.h \
|
||||
rio.c run-prv.h run.c tre-prv.h tre-ast.c tre-ast.h \
|
||||
tre-compile.c tre-compile.h tre-match-bt.c tre-match-pa.c \
|
||||
tre-match-ut.h tre-mem.c tre-mem.h tre-parse.c tre-parse.h \
|
||||
tre-stack.h tre-stack.c tre.c tree-prv.h tree.c uch-prop.h \
|
||||
uch-case.h utf16.c utf8.c utl-ass.c utl-skad.c utl-skad.h \
|
||||
utl-sort.c utl-str.c utl-sys.c utl.c val-prv.h val.c xma.c \
|
||||
hawk-cli.h hawk-fio.h hawk-mtx.h hawk-pio.h hawk-sio.h \
|
||||
hawk-tio.h cli-imp.h cli.c fio.c mtx.c pio.c sio.c syscall.h \
|
||||
tio.c std-prv.h std.c Hawk.cpp HawkStd.cpp mod-hawk.c \
|
||||
mod-hawk.h mod-math.c mod-math.h mod-str.c mod-str.h mod-sys.c \
|
||||
mod-sys.h
|
||||
am__objects_1 =
|
||||
am__objects_2 = $(am__objects_1)
|
||||
@ENABLE_CXX_TRUE@am__objects_3 = libhawk_la-Hawk.lo \
|
||||
@ -254,10 +255,10 @@ am_libhawk_la_OBJECTS = $(am__objects_2) libhawk_la-arr.lo \
|
||||
libhawk_la-utf16.lo libhawk_la-utf8.lo libhawk_la-utl-ass.lo \
|
||||
libhawk_la-utl-skad.lo libhawk_la-utl-sort.lo \
|
||||
libhawk_la-utl-str.lo libhawk_la-utl-sys.lo libhawk_la-utl.lo \
|
||||
libhawk_la-val.lo libhawk_la-cli.lo libhawk_la-fio.lo \
|
||||
libhawk_la-mtx.lo libhawk_la-pio.lo libhawk_la-sio.lo \
|
||||
libhawk_la-tio.lo libhawk_la-std.lo $(am__objects_3) \
|
||||
$(am__objects_4)
|
||||
libhawk_la-val.lo libhawk_la-xma.lo libhawk_la-cli.lo \
|
||||
libhawk_la-fio.lo libhawk_la-mtx.lo libhawk_la-pio.lo \
|
||||
libhawk_la-sio.lo libhawk_la-tio.lo libhawk_la-std.lo \
|
||||
$(am__objects_3) $(am__objects_4)
|
||||
libhawk_la_OBJECTS = $(am_libhawk_la_OBJECTS)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
@ -315,6 +316,7 @@ am__depfiles_remade = ./$(DEPDIR)/libhawk_hawk_la-mod-hawk.Plo \
|
||||
./$(DEPDIR)/libhawk_la-utl-str.Plo \
|
||||
./$(DEPDIR)/libhawk_la-utl-sys.Plo \
|
||||
./$(DEPDIR)/libhawk_la-utl.Plo ./$(DEPDIR)/libhawk_la-val.Plo \
|
||||
./$(DEPDIR)/libhawk_la-xma.Plo \
|
||||
./$(DEPDIR)/libhawk_math_la-mod-math.Plo \
|
||||
./$(DEPDIR)/libhawk_str_la-mod-str.Plo \
|
||||
./$(DEPDIR)/libhawk_sys_la-mod-sys.Plo
|
||||
@ -371,7 +373,7 @@ am__can_run_installinfo = \
|
||||
am__pkginclude_HEADERS_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \
|
||||
hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \
|
||||
hawk-map.h hawk-rbt.h hawk-pack1.h hawk-utl.h hawk-std.h \
|
||||
hawk-tre.h hawk-unpack.h Hawk.hpp HawkStd.hpp
|
||||
hawk-tre.h hawk-unpack.h hawk-xma.h Hawk.hpp HawkStd.hpp
|
||||
HEADERS = $(pkginclude_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
|
||||
$(LISP)hawk-cfg.h.in
|
||||
@ -579,7 +581,7 @@ CPPFLAGS_ALL_COMMON = \
|
||||
pkginclude_HEADERS = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \
|
||||
hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \
|
||||
hawk-map.h hawk-rbt.h hawk-pack1.h hawk-utl.h hawk-std.h \
|
||||
hawk-tre.h hawk-unpack.h $(am__append_7)
|
||||
hawk-tre.h hawk-unpack.h hawk-xma.h $(am__append_7)
|
||||
pkglib_LTLIBRARIES = libhawk.la $(am__append_15)
|
||||
libhawk_la_SOURCES = $(pkginclude_HEADERS) arr.c chr.c dir.c ecs-imp.h \
|
||||
ecs.c err-prv.h err.c err-sys.c fmt-imp.h fmt.c fnc-prv.h \
|
||||
@ -591,9 +593,10 @@ libhawk_la_SOURCES = $(pkginclude_HEADERS) arr.c chr.c dir.c ecs-imp.h \
|
||||
tre-parse.h tre-stack.h tre-stack.c tre.c tree-prv.h tree.c \
|
||||
uch-prop.h uch-case.h utf16.c utf8.c utl-ass.c utl-skad.c \
|
||||
utl-skad.h utl-sort.c utl-str.c utl-sys.c utl.c val-prv.h \
|
||||
val.c hawk-cli.h hawk-fio.h hawk-mtx.h hawk-pio.h hawk-sio.h \
|
||||
hawk-tio.h cli-imp.h cli.c fio.c mtx.c pio.c sio.c syscall.h \
|
||||
tio.c std-prv.h std.c $(am__append_8) $(am__append_9)
|
||||
val.c xma.c hawk-cli.h hawk-fio.h hawk-mtx.h hawk-pio.h \
|
||||
hawk-sio.h hawk-tio.h cli-imp.h cli.c fio.c mtx.c pio.c sio.c \
|
||||
syscall.h tio.c std-prv.h std.c $(am__append_8) \
|
||||
$(am__append_9)
|
||||
libhawk_la_CPPFLAGS = $(CPPFLAGS_ALL_COMMON) $(CPPFLAGS_PFMOD) \
|
||||
$(am__append_3)
|
||||
libhawk_la_LDFLAGS = $(LDFLAGS_ALL_COMMON) -version-info 1:0:0 -no-undefined
|
||||
@ -798,6 +801,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-utl-sys.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-utl.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-val.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-xma.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_math_la-mod-math.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_str_la-mod-str.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_sys_la-mod-sys.Plo@am__quote@ # am--include-marker
|
||||
@ -1133,6 +1137,13 @@ libhawk_la-val.lo: val.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhawk_la-val.lo `test -f 'val.c' || echo '$(srcdir)/'`val.c
|
||||
|
||||
libhawk_la-xma.lo: xma.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhawk_la-xma.lo -MD -MP -MF $(DEPDIR)/libhawk_la-xma.Tpo -c -o libhawk_la-xma.lo `test -f 'xma.c' || echo '$(srcdir)/'`xma.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-xma.Tpo $(DEPDIR)/libhawk_la-xma.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xma.c' object='libhawk_la-xma.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhawk_la-xma.lo `test -f 'xma.c' || echo '$(srcdir)/'`xma.c
|
||||
|
||||
libhawk_la-cli.lo: cli.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhawk_la-cli.lo -MD -MP -MF $(DEPDIR)/libhawk_la-cli.Tpo -c -o libhawk_la-cli.lo `test -f 'cli.c' || echo '$(srcdir)/'`cli.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-cli.Tpo $(DEPDIR)/libhawk_la-cli.Plo
|
||||
@ -1456,6 +1467,7 @@ distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-utl-sys.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-utl.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-val.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-xma.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_math_la-mod-math.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_str_la-mod-str.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_sys_la-mod-sys.Plo
|
||||
@ -1558,6 +1570,7 @@ maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-utl-sys.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-utl.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-val.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_la-xma.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_math_la-mod-math.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_str_la-mod-str.Plo
|
||||
-rm -f ./$(DEPDIR)/libhawk_sys_la-mod-sys.Plo
|
||||
|
@ -260,6 +260,12 @@ HAWK_EXPORT void* hawk_stdmodgetsym (
|
||||
const hawk_ooch_t* name
|
||||
);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
HAWK_EXPORT hawk_mmgr_t* hawk_get_sys_mmgr (
|
||||
void
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
243
hawk/lib/hawk-xma.h
Normal file
243
hawk/lib/hawk-xma.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-20202 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _HAWK_XMA_H_
|
||||
#define _HAWK_XMA_H_
|
||||
|
||||
/** @file
|
||||
* This file defines an extravagant memory allocator. Why? It may be so.
|
||||
* The memory allocator allows you to maintain memory blocks from a
|
||||
* larger memory chunk allocated with an outer memory allocator.
|
||||
* Typically, an outer memory allocator is a standard memory allocator
|
||||
* like malloc(). You can isolate memory blocks into a particular chunk.
|
||||
*
|
||||
* See the example below. Note it omits error handling.
|
||||
*
|
||||
* @code
|
||||
* #include <hawk-xma.h>
|
||||
* #include <stdio.h>
|
||||
* #include <stdarg.h>
|
||||
* void dumper (void* ctx, const char* fmt, ...)
|
||||
* {
|
||||
* va_list ap;
|
||||
* va_start (ap, fmt);
|
||||
* vfprintf (fmt, ap);
|
||||
* va_end (ap);
|
||||
* }
|
||||
* int main ()
|
||||
* {
|
||||
* hawk_xma_t* xma;
|
||||
* void* ptr1, * ptr2;
|
||||
*
|
||||
* // create a new memory allocator obtaining a 100K byte zone
|
||||
* // with the default memory allocator
|
||||
* xma = hawk_xma_open(HAWK_NULL, 0, 100000L);
|
||||
*
|
||||
* ptr1 = hawk_xma_alloc(xma, 5000); // allocate a 5K block from the zone
|
||||
* ptr2 = hawk_xma_alloc(xma, 1000); // allocate a 1K block from the zone
|
||||
* ptr1 = hawk_xma_realloc(xma, ptr1, 6000); // resize the 5K block to 6K.
|
||||
*
|
||||
* hawk_xma_dump (xma, dumper, HAWK_NULL); // dump memory blocks
|
||||
*
|
||||
* // the following two lines are not actually needed as the allocator
|
||||
* // is closed after them.
|
||||
* hawk_xma_free (xma, ptr2); // dispose of the 1K block
|
||||
* hawk_xma_free (xma, ptr1); // dispose of the 6K block
|
||||
*
|
||||
* hawk_xma_close (xma); // destroy the memory allocator
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#include <hawk-cmn.h>
|
||||
|
||||
#if defined(HAWK_BUILD_DEBUG)
|
||||
# define HAWK_XMA_ENABLE_STAT
|
||||
#endif
|
||||
|
||||
/** @struct hawk_xma_t
|
||||
* The hawk_xma_t type defines a simple memory allocator over a memory zone.
|
||||
* It can obtain a relatively large zone of memory and manage it.
|
||||
*/
|
||||
typedef struct hawk_xma_t hawk_xma_t;
|
||||
|
||||
/**
|
||||
* The hawk_xma_fblk_t type defines a memory block allocated.
|
||||
*/
|
||||
typedef struct hawk_xma_fblk_t hawk_xma_fblk_t;
|
||||
typedef struct hawk_xma_mblk_t hawk_xma_mblk_t;
|
||||
|
||||
#define HAWK_XMA_FIXED 32
|
||||
#define HAWK_XMA_SIZE_BITS ((HAWK_SIZEOF_OOW_T*8)-1)
|
||||
|
||||
struct hawk_xma_t
|
||||
{
|
||||
hawk_mmgr_t* _mmgr;
|
||||
|
||||
hawk_uint8_t* start; /* zone beginning */
|
||||
hawk_uint8_t* end; /* zone end */
|
||||
int internal;
|
||||
|
||||
/** pointer array to free memory blocks */
|
||||
hawk_xma_fblk_t* xfree[HAWK_XMA_FIXED + HAWK_XMA_SIZE_BITS + 1];
|
||||
|
||||
/** pre-computed value for fast xfree index calculation */
|
||||
hawk_oow_t bdec;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
struct
|
||||
{
|
||||
hawk_oow_t total;
|
||||
hawk_oow_t alloc;
|
||||
hawk_oow_t avail;
|
||||
hawk_oow_t nused;
|
||||
hawk_oow_t nfree;
|
||||
} stat;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* The hawk_xma_dumper_t type defines a printf-like output function
|
||||
* for hawk_xma_dump().
|
||||
*/
|
||||
typedef int (*hawk_xma_dumper_t) (
|
||||
void* ctx,
|
||||
const hawk_bch_t* fmt,
|
||||
...
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The hawk_xma_open() function creates a memory allocator. It obtains a memory
|
||||
* zone of the @a zonesize bytes with the memory manager @a mmgr. It also makes
|
||||
* available the extension area of the @a xtnsize bytes that you can get the
|
||||
* pointer to with hawk_xma_getxtn().
|
||||
*
|
||||
* @return pointer to a memory allocator on success, #HAWK_NULL on failure
|
||||
*/
|
||||
HAWK_EXPORT hawk_xma_t* hawk_xma_open (
|
||||
hawk_mmgr_t* mmgr, /**< memory manager */
|
||||
hawk_oow_t xtnsize, /**< extension size in bytes */
|
||||
void* zoneptr,
|
||||
hawk_oow_t zonesize /**< zone size in bytes */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_close() function destroys a memory allocator. It also frees
|
||||
* the memory zone obtained, which invalidates the memory blocks within
|
||||
* the zone. Call this function to destroy a memory allocator created with
|
||||
* hawk_xma_open().
|
||||
*/
|
||||
HAWK_EXPORT void hawk_xma_close (
|
||||
hawk_xma_t* xma /**< memory allocator */
|
||||
);
|
||||
|
||||
#if defined(HAWK_HAVE_INLINE)
|
||||
static HAWK_INLINE hawk_mmgr_t* hawk_xma_getmmgr (hawk_xma_t* xma) { return xma->_mmgr; }
|
||||
#else
|
||||
# define hawk_xma_getmmgr(xma) (((hawk_xma_t*)(xma))->_mmgr)
|
||||
#endif
|
||||
|
||||
#if defined(HAWK_HAVE_INLINE)
|
||||
static HAWK_INLINE void* hawk_xma_getxtn (hawk_xma_t* xma) { return (void*)(xma + 1); }
|
||||
#else
|
||||
#define hawk_xma_getxtn(xma) ((void*)((hawk_xma_t*)(xma) + 1))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The hawk_xma_init() initializes a memory allocator. If you have the hawk_xma_t
|
||||
* structure statically declared or already allocated, you may pass the pointer
|
||||
* to this function instead of calling hawk_xma_open(). It obtains a memory zone
|
||||
* of @a zonesize bytes with the memory manager @a mmgr. Unlike hawk_xma_open(),
|
||||
* it does not accept the extension size, thus not creating an extention area.
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
HAWK_EXPORT int hawk_xma_init (
|
||||
hawk_xma_t* xma, /**< memory allocator */
|
||||
hawk_mmgr_t* mmgr, /**< memory manager */
|
||||
void* zoneptr, /**< pointer to memory zone. if #HAWK_NULL, a zone is auto-created */
|
||||
hawk_oow_t zonesize /**< zone size in bytes */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_fini() function finalizes a memory allocator. Call this
|
||||
* function to finalize a memory allocator initialized with hawk_xma_init().
|
||||
*/
|
||||
HAWK_EXPORT void hawk_xma_fini (
|
||||
hawk_xma_t* xma /**< memory allocator */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_alloc() function allocates @a size bytes.
|
||||
* @return pointer to a memory block on success, #HAWK_NULL on failure
|
||||
*/
|
||||
HAWK_EXPORT void* hawk_xma_alloc (
|
||||
hawk_xma_t* xma, /**< memory allocator */
|
||||
hawk_oow_t size /**< size in bytes */
|
||||
);
|
||||
|
||||
HAWK_EXPORT void* hawk_xma_calloc (
|
||||
hawk_xma_t* xma,
|
||||
hawk_oow_t size
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_alloc() function resizes the memory block @a b to @a size bytes.
|
||||
* @return pointer to a resized memory block on success, #HAWK_NULL on failure
|
||||
*/
|
||||
HAWK_EXPORT void* hawk_xma_realloc (
|
||||
hawk_xma_t* xma, /**< memory allocator */
|
||||
void* b, /**< memory block */
|
||||
hawk_oow_t size /**< new size in bytes */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_alloc() function frees the memory block @a b.
|
||||
*/
|
||||
HAWK_EXPORT void hawk_xma_free (
|
||||
hawk_xma_t* xma, /**< memory allocator */
|
||||
void* b /**< memory block */
|
||||
);
|
||||
|
||||
/**
|
||||
* The hawk_xma_dump() function dumps the contents of the memory zone
|
||||
* with the output function @a dumper provided. The debug build shows
|
||||
* more statistical counters.
|
||||
*/
|
||||
HAWK_EXPORT void hawk_xma_dump (
|
||||
hawk_xma_t* xma, /**< memory allocator */
|
||||
hawk_xma_dumper_t dumper, /**< output function */
|
||||
void* ctx /**< first parameter to output function */
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -161,8 +161,10 @@ static int fnc_gc (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
|
||||
{
|
||||
hawk_int_t gen = -1;
|
||||
|
||||
#if defined(HAWK_ENABLE_GC)
|
||||
if (hawk_rtx_getnargs(rtx) >= 1 && hawk_rtx_valtoint(rtx, hawk_rtx_getarg(rtx, 0), &gen) <= -1) gen = -1;
|
||||
gen = hawk_rtx_gc(rtx, gen);
|
||||
#endif
|
||||
|
||||
HAWK_ASSERT (HAWK_IN_QUICKINT_RANGE(gen));
|
||||
hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, gen));
|
||||
|
@ -862,6 +862,10 @@ hawk_rtx_t* hawk_rtx_open (hawk_t* hawk, hawk_oow_t xtnsize, hawk_rio_cbs_t* rio
|
||||
rtx->_instsize = HAWK_SIZEOF(hawk_rtx_t);
|
||||
if (HAWK_UNLIKELY(init_rtx(rtx, hawk, rio) <= -1))
|
||||
{
|
||||
/* because the error information is in the gem part,
|
||||
* it should be ok to copy over rtx error to hawk even if
|
||||
* rtx initialization fails. */
|
||||
hawk_rtx_errortohawk (rtx, hawk);
|
||||
hawk_freemem (hawk, rtx);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
@ -6827,19 +6831,19 @@ static hawk_val_t** get_reference_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (vtype == HAWK_VAL_NIL /* || (rtx->hawk->opt.trait & HAWK_FLEXMAP) no flexmap because this is in a 'get' context. */)
|
||||
if (vtype == HAWK_VAL_NIL /* || (rtx->hawk->opt.trait & HAWK_FLEXMAP) no flexmap because this is in a 'get' context */)
|
||||
{
|
||||
if (container_vtype == HAWK_VAL_MAP)
|
||||
{
|
||||
v = assign_newmapval_in_map(rtx, map, str, len);
|
||||
if (HAWK_UNLIKELY(!v)) { ADJERR_LOC(rtx, &var->loc); goto oops; }
|
||||
if (HAWK_UNLIKELY(!v)) { ADJERR_LOC (rtx, &var->loc); goto oops; }
|
||||
vtype = HAWK_VAL_MAP;
|
||||
goto val_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = assign_newarrval_in_arr(rtx, arr, idx);
|
||||
if (HAWK_UNLIKELY(!v)) { ADJERR_LOC(rtx, &var->loc); goto oops; }
|
||||
if (HAWK_UNLIKELY(!v)) { ADJERR_LOC (rtx, &var->loc); goto oops; }
|
||||
vtype = HAWK_VAL_ARR;
|
||||
goto val_arr;
|
||||
}
|
||||
@ -7059,7 +7063,7 @@ static hawk_val_t* eval_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
||||
case HAWK_VAL_ARR:
|
||||
val_arr:
|
||||
idx = idxnde_to_int(rtx, remidx, &remidx);
|
||||
if (idx <= -1) goto oops;
|
||||
if (HAWK_UNLIKELY(idx <= -1)) goto oops;
|
||||
arr = ((hawk_val_arr_t*)v)->arr;
|
||||
break;
|
||||
|
||||
@ -7081,11 +7085,9 @@ static hawk_val_t* eval_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* var)
|
||||
goto val_arr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hawk_rtx_seterrnum (rtx, &var->loc, HAWK_ENOTIDXACC);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
hawk_rtx_seterrnum (rtx, &var->loc, HAWK_ENOTIDXACC);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -223,6 +223,11 @@ static hawk_mmgr_t sys_mmgr =
|
||||
HAWK_NULL
|
||||
};
|
||||
|
||||
|
||||
hawk_mmgr_t* hawk_get_sys_mmgr (void)
|
||||
{
|
||||
return &sys_mmgr;
|
||||
}
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
@ -907,9 +912,12 @@ hawk_t* hawk_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t
|
||||
|
||||
prm.logwrite = log_write;
|
||||
|
||||
if (!mmgr) mmgr = &sys_mmgr;
|
||||
if (!cmgr) cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8);
|
||||
|
||||
/* create an object */
|
||||
hawk = hawk_open(mmgr, HAWK_SIZEOF(xtn_t) + xtnsize, cmgr, &prm, errnum);
|
||||
if (!hawk) return HAWK_NULL;
|
||||
if (HAWK_UNLIKELY(!hawk)) return HAWK_NULL;
|
||||
|
||||
/* adjust the object size by the sizeof xtn_t so that hawk_getxtn() returns the right pointer. */
|
||||
hawk->_instsize += HAWK_SIZEOF(xtn_t);
|
||||
@ -2767,7 +2775,7 @@ static hawk_rtx_t* open_rtx_std (
|
||||
rio.console = hawk_rio_console;
|
||||
|
||||
rtx = hawk_rtx_open(hawk, HAWK_SIZEOF(rxtn_t) + xtnsize, &rio);
|
||||
if (!rtx) return HAWK_NULL;
|
||||
if (HAWK_UNLIKELY(!rtx)) return HAWK_NULL;
|
||||
|
||||
rtx->_instsize += HAWK_SIZEOF(rxtn_t);
|
||||
|
||||
@ -2841,7 +2849,7 @@ hawk_rtx_t* hawk_rtx_openstdwithbcstr (
|
||||
|
||||
#if defined(HAWK_OOCH_IS_UCH)
|
||||
xid = hawk_dupbtoucstr(hawk, id, &wcslen, 0);
|
||||
if (!xid) return HAWK_NULL;
|
||||
if (HAWK_UNLIKELY(!xid)) return HAWK_NULL;
|
||||
#else
|
||||
xid = (hawk_ooch_t*)id;
|
||||
#endif
|
||||
|
779
hawk/lib/xma.c
Normal file
779
hawk/lib/xma.c
Normal file
@ -0,0 +1,779 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <hawk-xma.h>
|
||||
#include "hawk-prv.h"
|
||||
|
||||
|
||||
#define ALIGN HAWK_SIZEOF(hawk_oow_t) /* this must be a power of 2 */
|
||||
#define MBLKHDRSIZE HAWK_SIZEOF(hawk_xma_mblk_t)
|
||||
#define MINBLKLEN HAWK_SIZEOF(hawk_xma_fblk_t) /* need space for the free links when the block is freeed */
|
||||
#define MINALLOCSIZE (ALIGN + ALIGN) /* as large as the free links in hawk_xma_fblk_t */
|
||||
|
||||
#define SYS_TO_USR(b) ((hawk_uint8_t*)(b) + MBLKHDRSIZE)
|
||||
#define USR_TO_SYS(b) ((hawk_uint8_t*)(b) - MBLKHDRSIZE)
|
||||
|
||||
/*
|
||||
* the xfree array is divided into three region
|
||||
* 0 ....................... FIXED ......................... XFIMAX-1 ... XFIMAX
|
||||
* | small fixed-size chains | large chains | huge chain |
|
||||
*/
|
||||
#define FIXED HAWK_XMA_FIXED
|
||||
#define XFIMAX(xma) (HAWK_COUNTOF(xma->xfree)-1)
|
||||
|
||||
#define mblk_size(b) (((hawk_xma_mblk_t*)(b))->size)
|
||||
#define mblk_prev_size(b) (((hawk_xma_mblk_t*)(b))->prev_size)
|
||||
#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))))
|
||||
|
||||
struct hawk_xma_mblk_t
|
||||
{
|
||||
hawk_oow_t prev_size;
|
||||
hawk_oow_t avail: 1;
|
||||
hawk_oow_t size: HAWK_XMA_SIZE_BITS;/**< block size */
|
||||
};
|
||||
|
||||
struct hawk_xma_fblk_t
|
||||
{
|
||||
hawk_oow_t prev_size;
|
||||
hawk_oow_t avail: 1;
|
||||
hawk_oow_t size: HAWK_XMA_SIZE_BITS;/**< block size */
|
||||
|
||||
/* these two fields 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_next; /**< link to the next free block */
|
||||
};
|
||||
|
||||
#if defined(VERIFY)
|
||||
static void DBG_VERIFY (hawk_xma_t* xma, const char* desc)
|
||||
{
|
||||
hawk_xma_mblk_t* tmp, * next;
|
||||
hawk_oow_t cnt;
|
||||
for (tmp = (hawk_xma_mblk_t*)xma->start, cnt = 0; (hawk_uint8_t*)tmp < xma->end; tmp = next, cnt++)
|
||||
{
|
||||
next = next_mblk(tmp);
|
||||
|
||||
if ((hawk_uint8_t*)tmp == xma->start)
|
||||
{
|
||||
HAWK_ASSERT (tmp->prev_size == 0);
|
||||
}
|
||||
if ((hawk_uint8_t*)next < xma->end)
|
||||
{
|
||||
HAWK_ASSERT (next->prev_size == tmp->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define DBG_VERIFY(xma, desc)
|
||||
#endif
|
||||
|
||||
static HAWK_INLINE hawk_oow_t szlog2 (hawk_oow_t n)
|
||||
{
|
||||
/*
|
||||
* 2**x = n;
|
||||
* x = log2(n);
|
||||
* -------------------------------------------
|
||||
* unsigned int x = 0;
|
||||
* while((n >> x) > 1) ++x;
|
||||
* return x;
|
||||
*/
|
||||
|
||||
#define BITS (HAWK_SIZEOF_OOW_T * 8)
|
||||
int x = BITS - 1;
|
||||
|
||||
#if HAWK_SIZEOF_OOW_T >= 128
|
||||
# error hawk_oow_t too large. unsupported platform
|
||||
#endif
|
||||
|
||||
#if HAWK_SIZEOF_OOW_T >= 64
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-128))) == 0) { x -= 256; n <<= 256; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 32
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-128))) == 0) { x -= 128; n <<= 128; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 16
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-64))) == 0) { x -= 64; n <<= 64; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 8
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-32))) == 0) { x -= 32; n <<= 32; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 4
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-16))) == 0) { x -= 16; n <<= 16; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 2
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-8))) == 0) { x -= 8; n <<= 8; }
|
||||
#endif
|
||||
#if HAWK_SIZEOF_OOW_T >= 1
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-4))) == 0) { x -= 4; n <<= 4; }
|
||||
#endif
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-2))) == 0) { x -= 2; n <<= 2; }
|
||||
if ((n & (~(hawk_oow_t)0 << (BITS-1))) == 0) { x -= 1; }
|
||||
|
||||
return x;
|
||||
#undef BITS
|
||||
}
|
||||
|
||||
static HAWK_INLINE hawk_oow_t getxfi (hawk_xma_t* xma, hawk_oow_t size)
|
||||
{
|
||||
hawk_oow_t xfi = ((size) / ALIGN) - 1;
|
||||
if (xfi >= FIXED) xfi = szlog2(size) - (xma)->bdec + FIXED;
|
||||
if (xfi > XFIMAX(xma)) xfi = XFIMAX(xma);
|
||||
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* xma;
|
||||
|
||||
xma = (hawk_xma_t*)HAWK_MMGR_ALLOC(mmgr, HAWK_SIZEOF(*xma) + xtnsize);
|
||||
if (HAWK_UNLIKELY(!xma)) return HAWK_NULL;
|
||||
|
||||
if (hawk_xma_init(xma, mmgr, zoneptr, zonesize) <= -1)
|
||||
{
|
||||
HAWK_MMGR_FREE (mmgr, xma);
|
||||
return HAWK_NULL;
|
||||
}
|
||||
|
||||
HAWK_MEMSET (xma + 1, 0, xtnsize);
|
||||
return xma;
|
||||
}
|
||||
|
||||
void hawk_xma_close (hawk_xma_t* xma)
|
||||
{
|
||||
hawk_xma_fini (xma);
|
||||
HAWK_MMGR_FREE (xma->_mmgr, xma);
|
||||
}
|
||||
|
||||
int hawk_xma_init (hawk_xma_t* xma, hawk_mmgr_t* mmgr, void* zoneptr, hawk_oow_t zonesize)
|
||||
{
|
||||
hawk_xma_fblk_t* free;
|
||||
hawk_oow_t xfi;
|
||||
int internal = 0;
|
||||
|
||||
if (!zoneptr)
|
||||
{
|
||||
/* round 'zonesize' to be the multiples of ALIGN */
|
||||
zonesize = HAWK_ALIGN_POW2(zonesize, ALIGN);
|
||||
|
||||
/* adjust 'zonesize' to be large enough to hold a single smallest block */
|
||||
if (zonesize < MINBLKLEN) zonesize = MINBLKLEN;
|
||||
|
||||
zoneptr = HAWK_MMGR_ALLOC(mmgr, zonesize);
|
||||
if (HAWK_UNLIKELY(!zoneptr)) return -1;
|
||||
|
||||
internal = 1;
|
||||
}
|
||||
|
||||
free = (hawk_xma_fblk_t*)zoneptr;
|
||||
|
||||
/* initialize the header part of the free chunk. the entire zone is a single free block */
|
||||
free->prev_size = 0;
|
||||
free->avail = 1;
|
||||
free->size = zonesize - MBLKHDRSIZE; /* size excluding the block header */
|
||||
free->free_prev = HAWK_NULL;
|
||||
free->free_next = HAWK_NULL;
|
||||
|
||||
HAWK_MEMSET (xma, 0, HAWK_SIZEOF(*xma));
|
||||
xma->_mmgr = mmgr;
|
||||
xma->bdec = szlog2(FIXED * ALIGN); /* precalculate the decrement value */
|
||||
|
||||
/* at this point, the 'free' chunk is a only block available */
|
||||
|
||||
/* get the free block index */
|
||||
xfi = getxfi(xma, free->size);
|
||||
/* locate it into an apporopriate slot */
|
||||
xma->xfree[xfi] = free;
|
||||
/* let it be the head, which is natural with only a block */
|
||||
xma->start = (hawk_uint8_t*)free;
|
||||
xma->end = xma->start + zonesize;
|
||||
xma->internal = internal;
|
||||
|
||||
/* initialize some statistical variables */
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.total = zonesize;
|
||||
xma->stat.alloc = 0;
|
||||
xma->stat.avail = zonesize - MBLKHDRSIZE;
|
||||
xma->stat.nfree = 1;
|
||||
xma->stat.nused = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hawk_xma_fini (hawk_xma_t* xma)
|
||||
{
|
||||
/* the head must point to the free chunk allocated in init().
|
||||
* let's deallocate it */
|
||||
if (xma->internal) HAWK_MMGR_FREE (xma->_mmgr, xma->start);
|
||||
xma->start = HAWK_NULL;
|
||||
xma->end = HAWK_NULL;
|
||||
}
|
||||
|
||||
static HAWK_INLINE void attach_to_freelist (hawk_xma_t* xma, hawk_xma_fblk_t* b)
|
||||
{
|
||||
/*
|
||||
* attach a block to a free list
|
||||
*/
|
||||
|
||||
/* get the free list index for the block size */
|
||||
hawk_oow_t xfi = getxfi(xma, b->size);
|
||||
|
||||
/* let it be the head of the free list doubly-linked */
|
||||
b->free_prev = HAWK_NULL;
|
||||
b->free_next = xma->xfree[xfi];
|
||||
if (xma->xfree[xfi]) xma->xfree[xfi]->free_prev = b;
|
||||
xma->xfree[xfi] = b;
|
||||
}
|
||||
|
||||
static HAWK_INLINE void detach_from_freelist (hawk_xma_t* xma, hawk_xma_fblk_t* b)
|
||||
{
|
||||
/* detach a block from a free list */
|
||||
hawk_xma_fblk_t* p, * n;
|
||||
|
||||
/* alias the previous and the next with short variable names */
|
||||
p = b->free_prev;
|
||||
n = b->free_next;
|
||||
|
||||
if (p)
|
||||
{
|
||||
/* the previous item exists. let its 'next' pointer point to
|
||||
* the block's next item. */
|
||||
p->free_next = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the previous item does not exist. the block is the first
|
||||
* item in the free list. */
|
||||
|
||||
hawk_oow_t xfi = getxfi(xma, b->size);
|
||||
HAWK_ASSERT (b == xma->xfree[xfi]);
|
||||
/* let's update the free list head */
|
||||
xma->xfree[xfi] = n;
|
||||
}
|
||||
|
||||
/* let the 'prev' pointer of the block's next item point to the
|
||||
* block's previous item */
|
||||
if (n) n->free_prev = p;
|
||||
}
|
||||
|
||||
static hawk_xma_fblk_t* alloc_from_freelist (hawk_xma_t* xma, hawk_oow_t xfi, hawk_oow_t size)
|
||||
{
|
||||
hawk_xma_fblk_t* free;
|
||||
|
||||
for (free = xma->xfree[xfi]; free; free = free->free_next)
|
||||
{
|
||||
if (free->size >= size)
|
||||
{
|
||||
hawk_oow_t rem;
|
||||
|
||||
detach_from_freelist (xma, free);
|
||||
|
||||
rem = free->size - size;
|
||||
if (rem >= MINBLKLEN)
|
||||
{
|
||||
hawk_xma_mblk_t* y, * z;
|
||||
|
||||
/* the remaining part is large enough to hold
|
||||
* another block. let's split it
|
||||
*/
|
||||
|
||||
/* shrink the size of the 'free' block */
|
||||
free->size = size;
|
||||
|
||||
/* let 'tmp' point to the remaining part */
|
||||
y = next_mblk(free); /* get the next adjacent block */
|
||||
|
||||
/* initialize some fields */
|
||||
y->avail = 1;
|
||||
y->size = rem - MBLKHDRSIZE;
|
||||
y->prev_size = free->size;
|
||||
|
||||
/* add the remaining part to the free list */
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)y);
|
||||
|
||||
z = next_mblk(y);
|
||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = y->size;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.avail -= MBLKHDRSIZE;
|
||||
#endif
|
||||
}
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
else
|
||||
{
|
||||
/* decrement the number of free blocks as the current
|
||||
* block is allocated as a whole without being split */
|
||||
xma->stat.nfree--;
|
||||
}
|
||||
#endif
|
||||
|
||||
free->avail = 0;
|
||||
/*
|
||||
free->free_next = HAWK_NULL;
|
||||
free->free_prev = HAWK_NULL;
|
||||
*/
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nused++;
|
||||
xma->stat.alloc += free->size;
|
||||
xma->stat.avail -= free->size;
|
||||
#endif
|
||||
return free;
|
||||
}
|
||||
}
|
||||
|
||||
return HAWK_NULL;
|
||||
}
|
||||
|
||||
|
||||
void* hawk_xma_alloc (hawk_xma_t* xma, hawk_oow_t size)
|
||||
{
|
||||
hawk_xma_fblk_t* free;
|
||||
hawk_oow_t xfi;
|
||||
|
||||
DBG_VERIFY (xma, "alloc start");
|
||||
|
||||
/* round up 'size' to the multiples of ALIGN */
|
||||
if (size < MINALLOCSIZE) size = MINALLOCSIZE;
|
||||
size = HAWK_ALIGN_POW2(size, ALIGN);
|
||||
|
||||
HAWK_ASSERT (size >= ALIGN);
|
||||
xfi = getxfi(xma, size);
|
||||
|
||||
/*if (xfi < XFIMAX(xma) && xma->xfree[xfi])*/
|
||||
if (xfi < FIXED && xma->xfree[xfi])
|
||||
{
|
||||
/* try the best fit */
|
||||
free = xma->xfree[xfi];
|
||||
|
||||
HAWK_ASSERT (free->avail != 0);
|
||||
HAWK_ASSERT (free->size == size);
|
||||
|
||||
detach_from_freelist (xma, free);
|
||||
free->avail = 0;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nfree--;
|
||||
xma->stat.nused++;
|
||||
xma->stat.alloc += free->size;
|
||||
xma->stat.avail -= free->size;
|
||||
#endif
|
||||
}
|
||||
else if (xfi == XFIMAX(xma))
|
||||
{
|
||||
/* huge block */
|
||||
free = alloc_from_freelist(xma, XFIMAX(xma), size);
|
||||
if (!free) return HAWK_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xfi >= FIXED)
|
||||
{
|
||||
/* get the block from its own large chain */
|
||||
free = alloc_from_freelist(xma, xfi, size);
|
||||
if (!free)
|
||||
{
|
||||
/* borrow a large block from the huge block chain */
|
||||
free = alloc_from_freelist(xma, XFIMAX(xma), size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* borrow a small block from the huge block chain */
|
||||
free = alloc_from_freelist(xma, XFIMAX(xma), size);
|
||||
if (!free) xfi = FIXED - 1;
|
||||
}
|
||||
|
||||
if (!free)
|
||||
{
|
||||
/* try each large block chain left */
|
||||
for (++xfi; xfi < XFIMAX(xma) - 1; xfi++)
|
||||
{
|
||||
free = alloc_from_freelist(xma, xfi, size);
|
||||
if (free) break;
|
||||
}
|
||||
if (!free) return HAWK_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_VERIFY (xma, "alloc end");
|
||||
return SYS_TO_USR(free);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
DBG_VERIFY (xma, "realloc merge start");
|
||||
/* rounds up 'size' to be multiples of ALIGN */
|
||||
if (size < MINALLOCSIZE) size = MINALLOCSIZE;
|
||||
size = HAWK_ALIGN_POW2(size, ALIGN);
|
||||
|
||||
if (size > blk->size)
|
||||
{
|
||||
/* grow the current block */
|
||||
hawk_oow_t req;
|
||||
hawk_xma_mblk_t* n;
|
||||
hawk_oow_t rem;
|
||||
|
||||
req = size - blk->size;
|
||||
|
||||
n = next_mblk(blk);
|
||||
/* check if the next adjacent block is available */
|
||||
if ((hawk_uint8_t*)n >= xma->end || !n->avail || req > n->size) return HAWK_NULL; /* no! */
|
||||
|
||||
HAWK_ASSERT (blk->size == n->prev_size);
|
||||
|
||||
/* let's merge the current block with the next block */
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)n);
|
||||
|
||||
rem = (MBLKHDRSIZE + n->size) - req;
|
||||
if (rem >= MINBLKLEN)
|
||||
{
|
||||
/*
|
||||
* the remaining part of the next block is large enough
|
||||
* to hold a block. break the next block.
|
||||
*/
|
||||
|
||||
hawk_xma_mblk_t* tmp;
|
||||
|
||||
blk->size += req;
|
||||
tmp = next_mblk(blk);
|
||||
tmp->avail = 1;
|
||||
tmp->size = rem - MBLKHDRSIZE;
|
||||
tmp->prev_size = blk->size;
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)tmp);
|
||||
|
||||
n = next_mblk(tmp);
|
||||
if ((hawk_uint8_t*)n < xma->end) n->prev_size = tmp->size;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.alloc += req;
|
||||
xma->stat.avail -= req; /* req + MBLKHDRSIZE(tmp) - MBLKHDRSIZE(n) */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 */
|
||||
blk->size += MBLKHDRSIZE + n->size;
|
||||
|
||||
n = next_mblk(blk);
|
||||
if ((hawk_uint8_t*)n < xma->end) n->prev_size = blk->size;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nfree--;
|
||||
xma->stat.alloc += MBLKHDRSIZE + n->size;
|
||||
xma->stat.avail -= n->size;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (size < blk->size)
|
||||
{
|
||||
/* shrink the block */
|
||||
hawk_oow_t rem = blk->size - size;
|
||||
if (rem >= MINBLKLEN)
|
||||
{
|
||||
hawk_xma_mblk_t* tmp;
|
||||
hawk_xma_mblk_t* n;
|
||||
|
||||
n = next_mblk(blk);
|
||||
|
||||
/* the leftover is large enough to hold a block of minimum size.
|
||||
* split the current block. let 'tmp' point to the leftover. */
|
||||
if ((hawk_uint8_t*)n < xma->end && n->avail)
|
||||
{
|
||||
/* let the leftover block merge with the next block */
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)n);
|
||||
|
||||
blk->size = size;
|
||||
|
||||
tmp = next_mblk(blk);
|
||||
tmp->avail = 1;
|
||||
tmp->size = rem + n->size;
|
||||
tmp->prev_size = blk->size;
|
||||
|
||||
/* add 'tmp' to the free list */
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)tmp);
|
||||
|
||||
n = next_mblk(tmp);
|
||||
if ((hawk_uint8_t*)n < xma->end) n->prev_size = tmp->size;
|
||||
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.alloc -= rem;
|
||||
/* rem - MBLKHDRSIZE(tmp) + MBLKHDRSIZE(n) */
|
||||
xma->stat.avail += rem;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* link the leftover block to the free list */
|
||||
blk->size = size;
|
||||
|
||||
tmp = next_mblk(blk);
|
||||
tmp->avail = 1;
|
||||
tmp->size = rem - MBLKHDRSIZE;
|
||||
tmp->prev_size = blk->size;
|
||||
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)tmp);
|
||||
/*n = next_mblk(tmp);
|
||||
if ((hawk_uint8_t*)n < xma->end)*/ n->prev_size = tmp->size;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nfree++;
|
||||
xma->stat.alloc -= rem;
|
||||
xma->stat.avail += tmp->size;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG_VERIFY (xma, "realloc merge end");
|
||||
return b;
|
||||
}
|
||||
|
||||
void* hawk_xma_calloc (hawk_xma_t* xma, hawk_oow_t size)
|
||||
{
|
||||
void* ptr = hawk_xma_alloc(xma, size);
|
||||
if (ptr) HAWK_MEMSET (ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* hawk_xma_realloc (hawk_xma_t* xma, void* b, hawk_oow_t size)
|
||||
{
|
||||
void* n;
|
||||
|
||||
if (b == HAWK_NULL)
|
||||
{
|
||||
/* 'realloc' with NULL is the same as 'alloc' */
|
||||
n = hawk_xma_alloc(xma, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* try reallocation by merging the adjacent continuous blocks */
|
||||
n = _realloc_merge (xma, b, size);
|
||||
if (!n)
|
||||
{
|
||||
/* reallocation by merging failed. fall back to the slow
|
||||
* allocation-copy-free scheme */
|
||||
n = hawk_xma_alloc(xma, size);
|
||||
if (n)
|
||||
{
|
||||
HAWK_MEMCPY (n, b, size);
|
||||
hawk_xma_free (xma, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void hawk_xma_free (hawk_xma_t* xma, void* b)
|
||||
{
|
||||
hawk_xma_mblk_t* blk = (hawk_xma_mblk_t*)USR_TO_SYS(b);
|
||||
hawk_xma_mblk_t* x, * y;
|
||||
|
||||
DBG_VERIFY (xma, "free start");
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
/* update statistical variables */
|
||||
xma->stat.nused--;
|
||||
xma->stat.alloc -= blk->size;
|
||||
#endif
|
||||
|
||||
x = prev_mblk(blk);
|
||||
y = next_mblk(blk);
|
||||
if (((hawk_uint8_t*)x >= xma->start && x->avail) && ((hawk_uint8_t*)y < xma->end && y->avail))
|
||||
{
|
||||
/*
|
||||
* Merge the block with surrounding blocks
|
||||
*
|
||||
* blk
|
||||
* |
|
||||
* v
|
||||
* +------------+------------+------------+------------+
|
||||
* | X | | Y | Z |
|
||||
* +------------+------------+------------+------------+
|
||||
*
|
||||
*
|
||||
* +--------------------------------------+------------+
|
||||
* | X | Z |
|
||||
* +--------------------------------------+------------+
|
||||
*
|
||||
*/
|
||||
|
||||
hawk_xma_mblk_t* z = next_mblk(y);
|
||||
hawk_oow_t ns = MBLKHDRSIZE + blk->size + MBLKHDRSIZE;
|
||||
hawk_oow_t bs = ns + y->size;
|
||||
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)x);
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)y);
|
||||
|
||||
x->size += bs;
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)x);
|
||||
|
||||
z = next_mblk(x);
|
||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = x->size;
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nfree--;
|
||||
xma->stat.avail += ns;
|
||||
#endif
|
||||
}
|
||||
else if ((hawk_uint8_t*)y < xma->end && y->avail)
|
||||
{
|
||||
/*
|
||||
* Merge the block with the next block
|
||||
*
|
||||
* blk
|
||||
* |
|
||||
* v
|
||||
* +------------+------------+------------+
|
||||
* | | Y | Z |
|
||||
* +------------+------------+------------+
|
||||
*
|
||||
*
|
||||
*
|
||||
* blk
|
||||
* |
|
||||
* v
|
||||
* +-------------------------+------------+
|
||||
* | | Z |
|
||||
* +-------------------------+------------+
|
||||
*
|
||||
*
|
||||
*/
|
||||
hawk_xma_mblk_t* z = next_mblk(y);
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.avail += blk->size + MBLKHDRSIZE;
|
||||
#endif
|
||||
|
||||
/* detach y from the free list */
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)y);
|
||||
|
||||
/* update the block availability */
|
||||
blk->avail = 1;
|
||||
/* update the block size. MBLKHDRSIZE for the header space in x */
|
||||
blk->size += MBLKHDRSIZE + y->size;
|
||||
|
||||
/* update the backward link of Y */
|
||||
if ((hawk_uint8_t*)z < xma->end) z->prev_size = blk->size;
|
||||
|
||||
/* attach blk to the free list */
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)blk);
|
||||
}
|
||||
else if ((hawk_uint8_t*)x >= xma->start && x->avail)
|
||||
{
|
||||
/*
|
||||
* Merge the block with the previous block
|
||||
*
|
||||
* blk
|
||||
* |
|
||||
* v
|
||||
* +------------+------------+------------+
|
||||
* | X | | Y |
|
||||
* +------------+------------+------------+
|
||||
*
|
||||
* +-------------------------+------------+
|
||||
* | X | Y |
|
||||
* +-------------------------+------------+
|
||||
*/
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.avail += MBLKHDRSIZE + blk->size;
|
||||
#endif
|
||||
|
||||
detach_from_freelist (xma, (hawk_xma_fblk_t*)x);
|
||||
|
||||
x->size += MBLKHDRSIZE + blk->size;
|
||||
if ((hawk_uint8_t*)y < xma->end) y->prev_size = x->size;
|
||||
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)x);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
blk->avail = 1;
|
||||
attach_to_freelist (xma, (hawk_xma_fblk_t*)blk);
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
xma->stat.nfree++;
|
||||
xma->stat.avail += blk->size;
|
||||
#endif
|
||||
}
|
||||
|
||||
DBG_VERIFY (xma, "free end");
|
||||
}
|
||||
|
||||
void hawk_xma_dump (hawk_xma_t* xma, hawk_xma_dumper_t dumper, void* ctx)
|
||||
{
|
||||
hawk_xma_mblk_t* tmp;
|
||||
hawk_oow_t fsum, asum;
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
hawk_oow_t isum;
|
||||
#endif
|
||||
|
||||
dumper (ctx, "<XMA DUMP>\n");
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
dumper (ctx, "== statistics ==\n");
|
||||
dumper (ctx, "total = %zu\n", xma->stat.total);
|
||||
dumper (ctx, "alloc = %zu\n", xma->stat.alloc);
|
||||
dumper (ctx, "avail = %zu\n", xma->stat.avail);
|
||||
#endif
|
||||
|
||||
dumper (ctx, "== blocks ==\n");
|
||||
dumper (ctx, " size avail address\n");
|
||||
for (tmp = (hawk_xma_mblk_t*)xma->start, fsum = 0, asum = 0; (hawk_uint8_t*)tmp < xma->end; tmp = next_mblk(tmp))
|
||||
{
|
||||
dumper (ctx, " %-18zu %-5u %p\n", tmp->size, (unsigned int)tmp->avail, tmp);
|
||||
if (tmp->avail) fsum += tmp->size;
|
||||
else asum += tmp->size;
|
||||
}
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
isum = (xma->stat.nfree + xma->stat.nused) * MBLKHDRSIZE;
|
||||
#endif
|
||||
|
||||
dumper (ctx, "---------------------------------------\n");
|
||||
dumper (ctx, "Allocated blocks: %18zu bytes\n", asum);
|
||||
dumper (ctx, "Available blocks: %18zu bytes\n", fsum);
|
||||
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
dumper (ctx, "Internal use : %18zu bytes\n", isum);
|
||||
dumper (ctx, "Total : %18zu bytes\n", (asum + fsum + isum));
|
||||
#endif
|
||||
|
||||
#if defined(HAWK_XMA_ENABLE_STAT)
|
||||
HAWK_ASSERT (asum == xma->stat.alloc);
|
||||
HAWK_ASSERT (fsum == xma->stat.avail);
|
||||
HAWK_ASSERT (isum == xma->stat.total - (xma->stat.alloc + xma->stat.avail));
|
||||
HAWK_ASSERT (asum + fsum + isum == xma->stat.total);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user