added fixed-size block allocator
This commit is contained in:
parent
8a19cce569
commit
70ca33c756
@ -1,7 +1,8 @@
|
|||||||
/** @page cmn COMMON FUNCTIONS
|
/** @page cmn COMMON FUNCTIONS
|
||||||
|
|
||||||
@section xma MEMORY ALLOCATOR
|
@section xma MEMORY ALLOCATOR
|
||||||
QSE provides a memory allocator #qse_xma_t for private heap management.
|
- QSE provides a memory allocator #qse_xma_t for private heap management.
|
||||||
|
- QSE provides a fixed-size block memory allocator #qse_fma_t.
|
||||||
|
|
||||||
@section rex REGULAR EXPRESSION
|
@section rex REGULAR EXPRESSION
|
||||||
QSE provides a regular expression processor #qse_rex_t.
|
QSE provides a regular expression processor #qse_rex_t.
|
||||||
|
@ -93,6 +93,8 @@ organized to dedicated modules. See relevant subpages for more information
|
|||||||
on each module.
|
on each module.
|
||||||
|
|
||||||
- @subpage cmn "Common Functions"
|
- @subpage cmn "Common Functions"
|
||||||
|
-# xma.h variable-size block memory allocator
|
||||||
|
-# fma.h fixed-size block memory allocator
|
||||||
- @subpage awk "AWK Interpreter"
|
- @subpage awk "AWK Interpreter"
|
||||||
- @subpage cut "CUT Text Cutter"
|
- @subpage cut "CUT Text Cutter"
|
||||||
- @subpage sed "SED Stream Editor"
|
- @subpage sed "SED Stream Editor"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pkgincludedir = $(includedir)/qse/cmn
|
pkgincludedir = $(includedir)/qse/cmn
|
||||||
|
|
||||||
pkginclude_HEADERS = \
|
pkginclude_HEADERS = \
|
||||||
mem.h xma.h chr.h str.h lda.h htb.h rbt.h \
|
mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
||||||
rex.h sll.h dll.h opt.h tio.h \
|
rex.h sll.h dll.h opt.h tio.h \
|
||||||
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
fio.h pio.h sio.h time.h misc.h main.h stdio.h
|
||||||
|
|
||||||
|
@ -51,9 +51,9 @@ CONFIG_CLEAN_FILES =
|
|||||||
CONFIG_CLEAN_VPATH_FILES =
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
SOURCES =
|
SOURCES =
|
||||||
DIST_SOURCES =
|
DIST_SOURCES =
|
||||||
am__pkginclude_HEADERS_DIST = mem.h xma.h chr.h str.h lda.h htb.h \
|
am__pkginclude_HEADERS_DIST = mem.h xma.h fma.h chr.h str.h lda.h \
|
||||||
rbt.h rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h \
|
htb.h rbt.h rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h \
|
||||||
misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
time.h misc.h main.h stdio.h Mmgr.hpp StdMmgr.hpp Mmged.hpp
|
||||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
am__vpath_adj = case $$p in \
|
am__vpath_adj = case $$p in \
|
||||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
@ -220,9 +220,9 @@ target_alias = @target_alias@
|
|||||||
top_build_prefix = @top_build_prefix@
|
top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
pkginclude_HEADERS = mem.h xma.h chr.h str.h lda.h htb.h rbt.h rex.h \
|
pkginclude_HEADERS = mem.h xma.h fma.h chr.h str.h lda.h htb.h rbt.h \
|
||||||
sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h main.h \
|
rex.h sll.h dll.h opt.h tio.h fio.h pio.h sio.h time.h misc.h \
|
||||||
stdio.h $(am__append_1)
|
main.h stdio.h $(am__append_1)
|
||||||
all: all-am
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
175
qse/include/qse/cmn/fma.h
Normal file
175
qse/include/qse/cmn/fma.h
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _QSE_CMN_FMA_H_
|
||||||
|
#define _QSE_CMN_FMA_H_
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
* This file defines a fixed-size block memory allocator. As the block size
|
||||||
|
* is known in advance, it achieves block allocation with little overhead.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* chunk head(cnkhead)
|
||||||
|
* | chunk
|
||||||
|
* | +---------------------------------------------+
|
||||||
|
* +--> | | f1 | f2 | | |
|
||||||
|
* +--|---------^------|----^--------------------+
|
||||||
|
* | | | |
|
||||||
|
* | +------+ +---+ +--------------+ chunk
|
||||||
|
* | | | |
|
||||||
|
* | +-----------------|----V--------------|-------+
|
||||||
|
* +---> | | | f3 | | f4 |
|
||||||
|
* +---------------------------------------^-----+
|
||||||
|
* |
|
||||||
|
* free block head (freeblk)
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* The diagram above assumes that f1, f2, f3, and f4 are free blocks.
|
||||||
|
* The chaining order depends on the allocation and deallocation order.
|
||||||
|
*
|
||||||
|
* See #qse_fma_t for more information. Use #qse_xma_t for variable-size block
|
||||||
|
* allocation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/types.h>
|
||||||
|
#include <qse/macros.h>
|
||||||
|
|
||||||
|
/** @struct qse_fma_cnk_t
|
||||||
|
* The qse_fma_cnk_t type defines a memory chunk header to hold memory blocks.
|
||||||
|
* The chunks added are maintained in a singly-linked list
|
||||||
|
*/
|
||||||
|
typedef struct qse_fma_cnk_t qse_fma_cnk_t;
|
||||||
|
struct qse_fma_cnk_t
|
||||||
|
{
|
||||||
|
qse_fma_cnk_t* next; /**< point to the next chunk */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @struct qse_fma_blk_t
|
||||||
|
* The qse_fma_blk_t type defines a memory block header to weave free blocks
|
||||||
|
* into a singly-linked list.
|
||||||
|
*/
|
||||||
|
typedef struct qse_fma_blk_t qse_fma_blk_t;
|
||||||
|
struct qse_fma_blk_t
|
||||||
|
{
|
||||||
|
qse_fma_blk_t* next; /**< point to the next block */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @struct qse_fma_t
|
||||||
|
* The qse_fma_t type defines a fixed-size block memory allocator.
|
||||||
|
* See the example below. Note that it omits error handling.
|
||||||
|
* @code
|
||||||
|
* qse_fma_t* fma;
|
||||||
|
* int* ptr1, * ptr2;
|
||||||
|
*
|
||||||
|
* // create a memory allocator for integer blocks up to 50.
|
||||||
|
* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
|
||||||
|
*
|
||||||
|
* // allocate two integer blocks
|
||||||
|
* ptr1 = (int*) qse_fma_alloc (fma);
|
||||||
|
* ptr2 = (int*) qse_fma_alloc (fma);
|
||||||
|
*
|
||||||
|
* *ptr1 = 20; *ptr2 = 99;
|
||||||
|
*
|
||||||
|
* // free the two blocks.
|
||||||
|
* qse_fma_free (fma, ptr1);
|
||||||
|
* qse_fma_free (fma, ptr2);
|
||||||
|
*
|
||||||
|
* // destroy the memory allocator
|
||||||
|
* qse_fma_close (fma);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
typedef struct qse_fma_t qse_fma_t;
|
||||||
|
struct qse_fma_t
|
||||||
|
{
|
||||||
|
QSE_DEFINE_COMMON_FIELDS (fma)
|
||||||
|
|
||||||
|
qse_size_t blksize; /**< block size */
|
||||||
|
qse_size_t maxblks; /**< maximum blocks in a chunk */
|
||||||
|
qse_size_t maxcnks; /**< maximum chunks */
|
||||||
|
|
||||||
|
qse_size_t numcnks; /**< current numbers of chunks */
|
||||||
|
qse_fma_cnk_t* cnkhead; /**< point to the first chunk added */
|
||||||
|
qse_fma_blk_t* freeblk; /**< point to the first free block */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSE_DEFINE_COMMON_FUNCTIONS (fma)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_open() function creates a memory allocator with an outer
|
||||||
|
* memory manager.
|
||||||
|
*/
|
||||||
|
qse_fma_t* qse_fma_open (
|
||||||
|
qse_mmgr_t* mmgr, /**< outer memory manager */
|
||||||
|
qse_size_t xtnsize, /**< extension size in bytes */
|
||||||
|
qse_size_t blksize, /**< block size in bytes */
|
||||||
|
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
|
||||||
|
qse_size_t maxcnks /**< maximum numbers of chunks */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_close() function destroys an memory allocator.
|
||||||
|
*/
|
||||||
|
void qse_fma_close (
|
||||||
|
qse_fma_t* fma /**< memory allocator */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_init() function initializes an memory allocator.
|
||||||
|
*/
|
||||||
|
qse_fma_t* qse_fma_init (
|
||||||
|
qse_fma_t* fma, /**< memory allocator */
|
||||||
|
qse_mmgr_t* mmgr, /**< outer memory manager */
|
||||||
|
qse_size_t blksize, /**< block size in bytes */
|
||||||
|
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
|
||||||
|
qse_size_t maxcnks /**< maximum numbers of chunks */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_fini() function finalizes an memory allocator.
|
||||||
|
*/
|
||||||
|
void qse_fma_fini (
|
||||||
|
qse_fma_t* fma /**< memory allocator */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_alloc() function allocates a block.
|
||||||
|
* @return block pointer on success, QSE_NULL on failure
|
||||||
|
*/
|
||||||
|
void* qse_fma_alloc (
|
||||||
|
qse_fma_t* fma /**< memory allocator */
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The qse_fma_alloc() function deallocates a block.
|
||||||
|
*/
|
||||||
|
void qse_fma_free (
|
||||||
|
qse_fma_t* fma, /**< memory allocator */
|
||||||
|
void* blk /**< memory block to free */
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -23,6 +23,11 @@
|
|||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
* This file defines an extravagant memory allocator. Why? It may be so.
|
* 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 #qse_xma_t for an example.
|
||||||
*/
|
*/
|
||||||
#include <qse/types.h>
|
#include <qse/types.h>
|
||||||
#include <qse/macros.h>
|
#include <qse/macros.h>
|
||||||
@ -173,7 +178,8 @@ void qse_xma_free (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_xma_dump() function dumps the contents of the memory zone
|
* The qse_xma_dump() function dumps the contents of the memory zone
|
||||||
* with the output function @a printf provided.
|
* with the output function @a printf provided. The debug build shows
|
||||||
|
* more statistical counters.
|
||||||
*/
|
*/
|
||||||
void qse_xma_dump (
|
void qse_xma_dump (
|
||||||
qse_xma_t* xma, /**< memory allocator */
|
qse_xma_t* xma, /**< memory allocator */
|
||||||
|
@ -5,7 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
|||||||
lib_LTLIBRARIES = libqsecmn.la
|
lib_LTLIBRARIES = libqsecmn.la
|
||||||
libqsecmn_la_SOURCES = \
|
libqsecmn_la_SOURCES = \
|
||||||
syscall.h mem.h \
|
syscall.h mem.h \
|
||||||
xma.c mem.c chr.c chr_cnv.c rex.c \
|
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
||||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||||
lda.c htb.c rbt.c sll.c dll.c opt.c \
|
lda.c htb.c rbt.c sll.c dll.c opt.c \
|
||||||
tio.c tio_get.c tio_put.c \
|
tio.c tio_get.c tio_put.c \
|
||||||
|
@ -73,11 +73,11 @@ am__base_list = \
|
|||||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||||
libqsecmn_la_DEPENDENCIES =
|
libqsecmn_la_DEPENDENCIES =
|
||||||
am_libqsecmn_la_OBJECTS = xma.lo mem.lo chr.lo chr_cnv.lo rex.lo \
|
am_libqsecmn_la_OBJECTS = mem.lo xma.lo fma.lo chr.lo chr_cnv.lo \
|
||||||
str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo htb.lo \
|
rex.lo str_bas.lo str_cnv.lo str_dyn.lo str_utl.lo lda.lo \
|
||||||
rbt.lo sll.lo dll.lo opt.lo tio.lo tio_get.lo tio_put.lo \
|
htb.lo rbt.lo sll.lo dll.lo opt.lo tio.lo tio_get.lo \
|
||||||
fio.lo pio.lo sio.lo time.lo misc.lo assert.lo main.lo \
|
tio_put.lo fio.lo pio.lo sio.lo time.lo misc.lo assert.lo \
|
||||||
stdio.lo
|
main.lo stdio.lo
|
||||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||||
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
libqsecmn_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
@ -262,7 +262,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
|||||||
lib_LTLIBRARIES = libqsecmn.la $(am__append_1)
|
lib_LTLIBRARIES = libqsecmn.la $(am__append_1)
|
||||||
libqsecmn_la_SOURCES = \
|
libqsecmn_la_SOURCES = \
|
||||||
syscall.h mem.h \
|
syscall.h mem.h \
|
||||||
xma.c mem.c chr.c chr_cnv.c rex.c \
|
mem.c xma.c fma.c chr.c chr_cnv.c rex.c \
|
||||||
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
str_bas.c str_cnv.c str_dyn.c str_utl.c \
|
||||||
lda.c htb.c rbt.c sll.c dll.c opt.c \
|
lda.c htb.c rbt.c sll.c dll.c opt.c \
|
||||||
tio.c tio_get.c tio_put.c \
|
tio.c tio_get.c tio_put.c \
|
||||||
@ -362,6 +362,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr_cnv.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr_cnv.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dll.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Plo@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Plo@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Plo@am__quote@
|
||||||
|
139
qse/lib/cmn/fma.c
Normal file
139
qse/lib/cmn/fma.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||||
|
This file is part of QSE.
|
||||||
|
|
||||||
|
QSE is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
QSE is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/cmn/fma.h>
|
||||||
|
#include "mem.h"
|
||||||
|
|
||||||
|
QSE_IMPLEMENT_COMMON_FUNCTIONS (fma)
|
||||||
|
|
||||||
|
qse_fma_t* qse_fma_open (
|
||||||
|
qse_mmgr_t* mmgr, qse_size_t xtnsize,
|
||||||
|
qse_size_t blksize, qse_size_t maxblks, qse_size_t maxcnks)
|
||||||
|
{
|
||||||
|
qse_fma_t* fma;
|
||||||
|
|
||||||
|
if (mmgr == QSE_NULL)
|
||||||
|
{
|
||||||
|
mmgr = QSE_MMGR_GETDFL();
|
||||||
|
|
||||||
|
QSE_ASSERTX (mmgr != QSE_NULL,
|
||||||
|
"Set the memory manager with QSE_MMGR_SETDFL()");
|
||||||
|
|
||||||
|
if (mmgr == QSE_NULL) return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fma = (qse_fma_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(*fma) + xtnsize);
|
||||||
|
if (fma == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
if (qse_fma_init (fma, mmgr, blksize, maxblks, maxcnks) == QSE_NULL)
|
||||||
|
{
|
||||||
|
QSE_MMGR_FREE (mmgr, fma);
|
||||||
|
return QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fma;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_fma_close (qse_fma_t* fma)
|
||||||
|
{
|
||||||
|
qse_fma_fini (fma);
|
||||||
|
QSE_MMGR_FREE (fma->mmgr, fma);
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_fma_t* qse_fma_init (
|
||||||
|
qse_fma_t* fma, qse_mmgr_t* mmgr,
|
||||||
|
qse_size_t blksize, qse_size_t maxblks, qse_size_t maxcnks)
|
||||||
|
{
|
||||||
|
QSE_MEMSET (fma, 0, QSE_SIZEOF(*fma));
|
||||||
|
fma->mmgr = mmgr;
|
||||||
|
|
||||||
|
if (blksize <= QSE_SIZEOF(qse_fma_blk_t))
|
||||||
|
blksize = QSE_SIZEOF(qse_fma_blk_t);
|
||||||
|
if (maxblks <= 0) maxblks = 1;
|
||||||
|
if (maxcnks <= 0) maxcnks = 1;
|
||||||
|
|
||||||
|
fma->blksize = blksize;
|
||||||
|
fma->maxblks = maxblks;
|
||||||
|
fma->maxcnks = maxcnks;
|
||||||
|
|
||||||
|
return fma;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_fma_fini (qse_fma_t* fma)
|
||||||
|
{
|
||||||
|
while (fma->cnkhead)
|
||||||
|
{
|
||||||
|
qse_fma_cnk_t* next = fma->cnkhead->next;
|
||||||
|
QSE_MMGR_FREE (fma->mmgr, fma->cnkhead);
|
||||||
|
fma->cnkhead = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QSE_INLINE qse_fma_cnk_t* add_chunk (qse_fma_t* fma)
|
||||||
|
{
|
||||||
|
qse_fma_cnk_t* cnk;
|
||||||
|
qse_fma_blk_t* blk;
|
||||||
|
qse_size_t i;
|
||||||
|
|
||||||
|
/* check if there are too many chunks */
|
||||||
|
if (fma->numcnks >= fma->maxcnks) return QSE_NULL;
|
||||||
|
|
||||||
|
/* allocate a chunk */
|
||||||
|
cnk = (qse_fma_cnk_t*) QSE_MMGR_ALLOC (fma->mmgr,
|
||||||
|
QSE_SIZEOF(*cnk) + fma->blksize * fma->maxblks);
|
||||||
|
if (cnk == QSE_NULL) return QSE_NULL;
|
||||||
|
|
||||||
|
/* weave the blocks in the chunk to the free block list */
|
||||||
|
fma->freeblk = (qse_fma_blk_t*)(cnk + 1);
|
||||||
|
blk = fma->freeblk;
|
||||||
|
for (i = 1; i < fma->maxblks; i++)
|
||||||
|
{
|
||||||
|
blk->next = (qse_fma_blk_t*)((qse_byte_t*)blk + fma->blksize);
|
||||||
|
blk = blk->next;
|
||||||
|
}
|
||||||
|
blk->next = QSE_NULL;
|
||||||
|
|
||||||
|
/* weave the chunk to the chunk list */
|
||||||
|
cnk->next = fma->cnkhead;
|
||||||
|
fma->cnkhead = cnk;
|
||||||
|
fma->numcnks++;
|
||||||
|
|
||||||
|
return cnk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* qse_fma_alloc (qse_fma_t* fma)
|
||||||
|
{
|
||||||
|
void* blk;
|
||||||
|
|
||||||
|
if ((blk = fma->freeblk) == QSE_NULL)
|
||||||
|
{
|
||||||
|
if (add_chunk (fma) == QSE_NULL) return QSE_NULL;
|
||||||
|
blk = fma->freeblk;
|
||||||
|
}
|
||||||
|
fma->freeblk = fma->freeblk->next;
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_fma_free (qse_fma_t* fma, void* blk)
|
||||||
|
{
|
||||||
|
((qse_fma_blk_t*)blk)->next = fma->freeblk;
|
||||||
|
fma->freeblk = blk;
|
||||||
|
}
|
||||||
|
|
@ -142,7 +142,9 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
|
|||||||
qse_xma_blk_t* free;
|
qse_xma_blk_t* free;
|
||||||
qse_size_t xfi;
|
qse_size_t xfi;
|
||||||
|
|
||||||
|
/* round 'zonesize' to be the multiples of ALIGN */
|
||||||
zonesize = ((zonesize + ALIGN - 1) / ALIGN) * ALIGN;
|
zonesize = ((zonesize + ALIGN - 1) / ALIGN) * ALIGN;
|
||||||
|
|
||||||
/* adjust 'zonesize' to be large enough to hold a single smallest block */
|
/* adjust 'zonesize' to be large enough to hold a single smallest block */
|
||||||
if (zonesize < MINBLKLEN) zonesize = MINBLKLEN;
|
if (zonesize < MINBLKLEN) zonesize = MINBLKLEN;
|
||||||
|
|
||||||
@ -162,10 +164,14 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
|
|||||||
xma->mmgr = mmgr;
|
xma->mmgr = mmgr;
|
||||||
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 */
|
/* at this point, the 'free' chunk is a only block available */
|
||||||
|
|
||||||
|
/* get the free block index */
|
||||||
xfi = getxfi(xma,free->size);
|
xfi = getxfi(xma,free->size);
|
||||||
xma->xfree[xfi] = free; /* locate it at the right slot */
|
/* locate it into an apporopriate slot */
|
||||||
xma->head = free; /* store it for furture reference */
|
xma->xfree[xfi] = free;
|
||||||
|
/* let it be the head, which is natural with only a block */
|
||||||
|
xma->head = free;
|
||||||
|
|
||||||
/* initialize some statistical variables */
|
/* initialize some statistical variables */
|
||||||
#ifdef QSE_XMA_ENABLE_STAT
|
#ifdef QSE_XMA_ENABLE_STAT
|
||||||
@ -181,13 +187,21 @@ qse_xma_t* qse_xma_init (qse_xma_t* xma, qse_mmgr_t* mmgr, qse_size_t zonesize)
|
|||||||
|
|
||||||
void qse_xma_fini (qse_xma_t* xma)
|
void qse_xma_fini (qse_xma_t* xma)
|
||||||
{
|
{
|
||||||
|
/* the head must point to the free chunk allocated in init().
|
||||||
|
* let's deallocate it */
|
||||||
QSE_MMGR_FREE (xma->mmgr, xma->head);
|
QSE_MMGR_FREE (xma->mmgr, xma->head);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* attach a block to a free list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* get the free list index for the block size */
|
||||||
qse_size_t xfi = getxfi(xma,b->size);
|
qse_size_t xfi = getxfi(xma,b->size);
|
||||||
|
|
||||||
|
/* let it be the head of the free list doubly-linked */
|
||||||
b->f.prev = QSE_NULL;
|
b->f.prev = QSE_NULL;
|
||||||
b->f.next = xma->xfree[xfi];
|
b->f.next = xma->xfree[xfi];
|
||||||
if (xma->xfree[xfi]) xma->xfree[xfi]->f.prev = b;
|
if (xma->xfree[xfi]) xma->xfree[xfi]->f.prev = b;
|
||||||
@ -196,21 +210,34 @@ static QSE_INLINE void attach_to_freelist (qse_xma_t* xma, qse_xma_blk_t* b)
|
|||||||
|
|
||||||
static QSE_INLINE void detach_from_freelist (qse_xma_t* xma, qse_xma_blk_t* b)
|
static QSE_INLINE void detach_from_freelist (qse_xma_t* xma, qse_xma_blk_t* b)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* detach a block from a free list
|
||||||
|
*/
|
||||||
qse_xma_blk_t* p, * n;
|
qse_xma_blk_t* p, * n;
|
||||||
|
|
||||||
|
/* alias the previous and the next with short variable names */
|
||||||
p = b->f.prev;
|
p = b->f.prev;
|
||||||
n = b->f.next;
|
n = b->f.next;
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
|
/* the previous item exists. let its 'next' pointer point to
|
||||||
|
* the block's next item. */
|
||||||
p->f.next = n;
|
p->f.next = n;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* the previous item does not exist. the block is the first
|
||||||
|
* item in the free list. */
|
||||||
|
|
||||||
qse_size_t xfi = getxfi(xma,b->size);
|
qse_size_t xfi = getxfi(xma,b->size);
|
||||||
QSE_ASSERT (b == xma->xfree[xfi]);
|
QSE_ASSERT (b == xma->xfree[xfi]);
|
||||||
|
/* let's update the free list head */
|
||||||
xma->xfree[xfi] = n;
|
xma->xfree[xfi] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* let the 'prev' pointer of the block's next item point to the
|
||||||
|
* block's previous item */
|
||||||
if (n) n->f.prev = p;
|
if (n) n->f.prev = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,22 +390,32 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size)
|
|||||||
|
|
||||||
if (size > blk->size)
|
if (size > blk->size)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* grow the current block
|
||||||
|
*/
|
||||||
|
|
||||||
qse_size_t req = size - blk->size;
|
qse_size_t req = size - blk->size;
|
||||||
qse_xma_blk_t* n;
|
qse_xma_blk_t* n;
|
||||||
qse_size_t rem;
|
qse_size_t rem;
|
||||||
|
|
||||||
n = blk->b.next;
|
n = blk->b.next;
|
||||||
if (!n || !n->avail || req > n->size) return QSE_NULL;
|
|
||||||
|
|
||||||
/* merge the current block with the next block
|
/* check if the next adjacent block is available */
|
||||||
* if it is available */
|
if (!n || !n->avail || req > n->size) return QSE_NULL; /* no! */
|
||||||
|
|
||||||
|
/* let's merge the current block with the next block */
|
||||||
detach_from_freelist (xma, n);
|
detach_from_freelist (xma, n);
|
||||||
|
|
||||||
rem = (HDRSIZE + n->size) - req;
|
rem = (HDRSIZE + n->size) - req;
|
||||||
if (rem >= MINBLKLEN)
|
if (rem >= MINBLKLEN)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* the remaining part of the next block is large enough
|
||||||
|
* to hold a block. break the next block.
|
||||||
|
*/
|
||||||
|
|
||||||
qse_xma_blk_t* tmp;
|
qse_xma_blk_t* tmp;
|
||||||
|
|
||||||
/* store n->b.next in case 'tmp' begins somewhere
|
/* store n->b.next in case 'tmp' begins somewhere
|
||||||
* in the header part of n */
|
* in the header part of n */
|
||||||
qse_xma_blk_t* nn = n->b.next;
|
qse_xma_blk_t* nn = n->b.next;
|
||||||
@ -404,6 +441,8 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* the remaining part of the next block is negligible.
|
||||||
|
* utilize the whole block by merging to the resizing block */
|
||||||
blk->size += HDRSIZE + n->size;
|
blk->size += HDRSIZE + n->size;
|
||||||
blk->b.next = n->b.next;
|
blk->b.next = n->b.next;
|
||||||
if (n->b.next) n->b.next->b.prev = blk;
|
if (n->b.next) n->b.next->b.prev = blk;
|
||||||
@ -414,80 +453,13 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size)
|
|||||||
xma->stat.avail -= n->size;
|
xma->stat.avail -= n->size;
|
||||||
#endif
|
#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)
|
else if (size < blk->size)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* shrink the block
|
||||||
|
*/
|
||||||
|
|
||||||
qse_size_t rem = blk->size - size;
|
qse_size_t rem = blk->size - size;
|
||||||
if (rem >= MINBLKLEN)
|
if (rem >= MINBLKLEN)
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
AM_CPPFLAGS = -I$(top_srcdir)/include -DNDEBUG
|
||||||
|
|
||||||
bin_PROGRAMS = xma chr str sll lda htb rbt fio pio sio time main rex01
|
bin_PROGRAMS = xma fma 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
|
xma_SOURCES = xma.c
|
||||||
|
fma_SOURCES = fma.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
|
||||||
|
@ -34,10 +34,10 @@ PRE_UNINSTALL = :
|
|||||||
POST_UNINSTALL = :
|
POST_UNINSTALL = :
|
||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
bin_PROGRAMS = xma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) sll$(EXEEXT) \
|
bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) \
|
||||||
lda$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) \
|
sll$(EXEEXT) lda$(EXEEXT) htb$(EXEEXT) rbt$(EXEEXT) \
|
||||||
pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) \
|
fio$(EXEEXT) pio$(EXEEXT) sio$(EXEEXT) time$(EXEEXT) \
|
||||||
rex01$(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
|
||||||
@ -62,6 +62,10 @@ am_fio_OBJECTS = fio.$(OBJEXT)
|
|||||||
fio_OBJECTS = $(am_fio_OBJECTS)
|
fio_OBJECTS = $(am_fio_OBJECTS)
|
||||||
fio_LDADD = $(LDADD)
|
fio_LDADD = $(LDADD)
|
||||||
fio_DEPENDENCIES =
|
fio_DEPENDENCIES =
|
||||||
|
am_fma_OBJECTS = fma.$(OBJEXT)
|
||||||
|
fma_OBJECTS = $(am_fma_OBJECTS)
|
||||||
|
fma_LDADD = $(LDADD)
|
||||||
|
fma_DEPENDENCIES =
|
||||||
am_htb_OBJECTS = htb.$(OBJEXT)
|
am_htb_OBJECTS = htb.$(OBJEXT)
|
||||||
htb_OBJECTS = $(am_htb_OBJECTS)
|
htb_OBJECTS = $(am_htb_OBJECTS)
|
||||||
htb_LDADD = $(LDADD)
|
htb_LDADD = $(LDADD)
|
||||||
@ -119,14 +123,14 @@ CCLD = $(CC)
|
|||||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||||
$(LDFLAGS) -o $@
|
$(LDFLAGS) -o $@
|
||||||
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(htb_SOURCES) $(lda_SOURCES) \
|
SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(fma_SOURCES) $(htb_SOURCES) \
|
||||||
$(main_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) $(rex01_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) \
|
$(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) $(xma_SOURCES)
|
$(time_SOURCES) $(xma_SOURCES)
|
||||||
|
DIST_SOURCES = $(chr_SOURCES) $(fio_SOURCES) $(fma_SOURCES) \
|
||||||
|
$(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(pio_SOURCES) \
|
||||||
|
$(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) \
|
||||||
|
$(str_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)
|
||||||
@ -272,6 +276,7 @@ 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
|
xma_SOURCES = xma.c
|
||||||
|
fma_SOURCES = fma.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
|
||||||
@ -367,6 +372,9 @@ chr$(EXEEXT): $(chr_OBJECTS) $(chr_DEPENDENCIES)
|
|||||||
fio$(EXEEXT): $(fio_OBJECTS) $(fio_DEPENDENCIES)
|
fio$(EXEEXT): $(fio_OBJECTS) $(fio_DEPENDENCIES)
|
||||||
@rm -f fio$(EXEEXT)
|
@rm -f fio$(EXEEXT)
|
||||||
$(LINK) $(fio_OBJECTS) $(fio_LDADD) $(LIBS)
|
$(LINK) $(fio_OBJECTS) $(fio_LDADD) $(LIBS)
|
||||||
|
fma$(EXEEXT): $(fma_OBJECTS) $(fma_DEPENDENCIES)
|
||||||
|
@rm -f fma$(EXEEXT)
|
||||||
|
$(LINK) $(fma_OBJECTS) $(fma_LDADD) $(LIBS)
|
||||||
htb$(EXEEXT): $(htb_OBJECTS) $(htb_DEPENDENCIES)
|
htb$(EXEEXT): $(htb_OBJECTS) $(htb_DEPENDENCIES)
|
||||||
@rm -f htb$(EXEEXT)
|
@rm -f htb$(EXEEXT)
|
||||||
$(LINK) $(htb_OBJECTS) $(htb_LDADD) $(LIBS)
|
$(LINK) $(htb_OBJECTS) $(htb_LDADD) $(LIBS)
|
||||||
@ -409,6 +417,7 @@ distclean-compile:
|
|||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chr.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fio.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
|
||||||
|
70
qse/samples/cmn/fma.c
Normal file
70
qse/samples/cmn/fma.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <qse/cmn/fma.h>
|
||||||
|
#include <qse/cmn/stdio.h>
|
||||||
|
|
||||||
|
#define R(f) \
|
||||||
|
do { \
|
||||||
|
qse_printf (QSE_T("== %s ==\n"), QSE_T(#f)); \
|
||||||
|
if (f() == -1) return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int test1 ()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int* ptr[100];
|
||||||
|
|
||||||
|
qse_fma_t* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
|
||||||
|
if (fma == QSE_NULL)
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("cannot open fma\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
ptr[i] = qse_fma_alloc (fma);
|
||||||
|
if (ptr[i])
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("%d %p\n"), i, ptr[i]);
|
||||||
|
*(ptr[i]) = i;
|
||||||
|
}
|
||||||
|
else qse_printf (QSE_T("%d FAIL\n"), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 30; i+=2)
|
||||||
|
{
|
||||||
|
if (ptr[i])
|
||||||
|
{
|
||||||
|
qse_fma_free (fma, ptr[i]);
|
||||||
|
ptr[i] = QSE_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
if (ptr[i])
|
||||||
|
{
|
||||||
|
qse_fma_free (fma, ptr[i]);
|
||||||
|
ptr[i] = QSE_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
ptr[i] = qse_fma_alloc (fma);
|
||||||
|
if (ptr[i])
|
||||||
|
{
|
||||||
|
qse_printf (QSE_T("%d %p\n"), i, ptr[i]);
|
||||||
|
*(ptr[i]) = i;
|
||||||
|
}
|
||||||
|
else qse_printf (QSE_T("%d FAIL\n"), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
qse_fma_close (fma);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
R (test1);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user