forked from enlightenment/efl
efl: simplify mempools, nuke some and make remaining statically built.
Now we always build the following memory pools statically: - pass_through: calls malloc/free directly, useful to debug. - chained_pool: default for ages. - one_big: used by some embedded systems (should we remove?) Removed: - ememoa_fixed and ememoa_unknown: depends on a separate lib, not supported? - buddy: nobody uses it? NOTE: we do not need the src/modules/eina/mp/*/Makefile.am anymore since they are statically built. But I'll keep these and the references in src/modules/eina/mp/Makefile.am SVN revision: 77792
This commit is contained in:
parent
59ed22a467
commit
4d35e4ca03
77
configure.ac
77
configure.ac
|
@ -343,23 +343,7 @@ if test "x${have_stringshare_usage}" = "xyes"; then
|
|||
fi
|
||||
|
||||
# Choose best memory pool
|
||||
AC_ARG_ENABLE([default-mempool],
|
||||
[AC_HELP_STRING([--enable-default-mempool], [Default memory allocator could be faster for some computer. @<:@default=disabled@:>@])],
|
||||
[
|
||||
if test "x${enableval}" = "xyes"; then
|
||||
have_default_mempool="yes"
|
||||
else
|
||||
have_default_mempool="no"
|
||||
fi
|
||||
],
|
||||
[have_default_mempool="no"])
|
||||
|
||||
AC_MSG_CHECKING([whether to use default mempool allocator])
|
||||
AC_MSG_RESULT([${have_default_mempool}])
|
||||
|
||||
if test "x${have_default_mempool}" = "xyes" ; then
|
||||
EINA_CONFIGURE_DEFAULT_MEMPOOL="#define EINA_DEFAULT_MEMPOOL"
|
||||
fi
|
||||
EINA_CONFIGURE_DEFAULT_MEMPOOL="#define EINA_DEFAULT_MEMPOOL"
|
||||
AC_SUBST([EINA_CONFIGURE_DEFAULT_MEMPOOL])
|
||||
|
||||
### Checks for programs
|
||||
|
@ -431,36 +415,11 @@ if test "x${ac_cv_func_malloc_usable_size}" = "xyes" && test "x${want_debug_mall
|
|||
fi
|
||||
|
||||
## Modules
|
||||
|
||||
# Check ememoa memory pool library
|
||||
|
||||
AC_ARG_ENABLE([ememoa],
|
||||
[AC_HELP_STRING([--enable-ememoa], [build ememoa memory pool module @<:@default=yes@:>@])],
|
||||
[
|
||||
if test "x${enableval}" = "xyes" ; then
|
||||
enable_ememoa="yes"
|
||||
else
|
||||
enable_ememoa="no"
|
||||
fi
|
||||
],
|
||||
[enable_ememoa="yes"])
|
||||
|
||||
AC_MSG_CHECKING([whether to use ememoa for memory pool])
|
||||
AC_MSG_RESULT([${enable_ememoa}])
|
||||
|
||||
if test "x${enable_ememoa}" = "xyes" ; then
|
||||
PKG_CHECK_MODULES([EMEMOA],
|
||||
[ememoa >= 0.0.26 ],
|
||||
[enable_ememoa="yes"],
|
||||
[enable_ememoa="no"])
|
||||
fi
|
||||
|
||||
if ! test "x${requirements_pc_deps_eina}" = "x" ; then
|
||||
PKG_CHECK_MODULES([EINA], [${requirements_pc_deps_eina}])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
# TODO: add once ecore-evas is merged:
|
||||
|
@ -596,24 +555,9 @@ AC_SUBST(EINA_CONFIGURE_HAVE_ON_OFF_THREADS)
|
|||
AM_CONDITIONAL([EINA_ON_OFF_THREADS], [! test "x${efl_have_on_off_threads}" = "xno"])
|
||||
|
||||
### Modules
|
||||
|
||||
if test "x${have_default_mempool}" = "xyes" ; then
|
||||
enable_chained_pool="no"
|
||||
enable_pass_through="static"
|
||||
else
|
||||
enable_chained_pool="static"
|
||||
enable_pass_through="no"
|
||||
fi
|
||||
|
||||
enable_one_big="static"
|
||||
|
||||
EINA_CHECK_MODULE([chained-pool], [${enable_chained_pool}], [chained pool])
|
||||
EINA_CHECK_MODULE([ememoa-fixed], [${enable_ememoa}], [ememoa fixed])
|
||||
EINA_CHECK_MODULE([ememoa-unknown], [${enable_ememoa}], [ememoa unknown])
|
||||
EINA_CHECK_MODULE([fixed-bitmap], [no], [fixed bitmap])
|
||||
EINA_CHECK_MODULE([pass-through], [${enable_pass_through}], [pass through])
|
||||
EINA_CHECK_MODULE([buddy], [no], [buddy])
|
||||
EINA_CHECK_MODULE([one-big], [${enable_one_big}], [one big])
|
||||
EINA_CHECK_MODULE([chained-pool], [static], [chained pool])
|
||||
EINA_CHECK_MODULE([pass-through], [static], [pass through])
|
||||
EINA_CHECK_MODULE([one-big], [static], [one big])
|
||||
|
||||
|
||||
#### End of Eina
|
||||
|
@ -912,11 +856,7 @@ src/modules/Makefile
|
|||
src/modules/eina/Makefile
|
||||
src/modules/eina/mp/Makefile
|
||||
src/modules/eina/mp/chained_pool/Makefile
|
||||
src/modules/eina/mp/ememoa_fixed/Makefile
|
||||
src/modules/eina/mp/ememoa_unknown/Makefile
|
||||
src/modules/eina/mp/pass_through/Makefile
|
||||
src/modules/eina/mp/fixed_bitmap/Makefile
|
||||
src/modules/eina/mp/buddy/Makefile
|
||||
src/modules/eina/mp/one_big/Makefile
|
||||
src/scripts/Makefile
|
||||
src/scripts/eina/Makefile
|
||||
|
@ -966,15 +906,6 @@ echo " File dirfd...........: ${efl_func_dirfd}"
|
|||
echo " File xattr...........: ${efl_func_setxattr}"
|
||||
echo " shm_open.............: ${efl_func_shm_open}"
|
||||
echo
|
||||
echo " Memory pools:"
|
||||
echo " Buddy..............: ${enable_buddy}"
|
||||
echo " Chained pool.......: ${enable_chained_pool}"
|
||||
echo " Ememoa fixed.......: ${enable_ememoa_fixed}"
|
||||
echo " Ememoa unknown.....: ${enable_ememoa_unknown}"
|
||||
echo " Fixed bitmap.......: ${enable_fixed_bitmap}"
|
||||
echo " One big............: ${enable_one_big}"
|
||||
echo " Pass through.......: ${enable_pass_through}"
|
||||
echo
|
||||
echo "Compilation............: make (or gmake)"
|
||||
echo " CPPFLAGS.............: $CPPFLAGS"
|
||||
echo " CFLAGS...............: $CFLAGS"
|
||||
|
|
|
@ -173,26 +173,10 @@ eina_binbuf_template_c.x
|
|||
|
||||
|
||||
|
||||
if EINA_STATIC_BUILD_BUDDY
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/buddy/eina_buddy.c
|
||||
endif
|
||||
|
||||
if EINA_STATIC_BUILD_CHAINED_POOL
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/chained_pool/eina_chained_mempool.c
|
||||
endif
|
||||
|
||||
if EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/ememoa_fixed/eina_ememoa_fixed.c
|
||||
endif
|
||||
|
||||
if EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/ememoa_unknown/eina_ememoa_unknown.c
|
||||
endif
|
||||
|
||||
if EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/fixed_bitmap/eina_fixed_bitmap.c
|
||||
endif
|
||||
|
||||
if EINA_STATIC_BUILD_ONE_BIG
|
||||
libeina_la_SOURCES += $(top_srcdir)/src/modules/eina/mp/one_big/eina_one_big.c
|
||||
endif
|
||||
|
|
|
@ -114,31 +114,11 @@ on_error:
|
|||
|
||||
/* Built-in backend's prototypes */
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_BUDDY
|
||||
Eina_Bool buddy_init(void);
|
||||
void buddy_shutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
|
||||
Eina_Bool chained_init(void);
|
||||
void chained_shutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
Eina_Bool ememoa_fixed_init(void);
|
||||
void ememoa_fixed_shutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
Eina_Bool ememoa_unknown_init(void);
|
||||
void ememoa_unknown_shutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
Eina_Bool fixed_bitmap_init(void);
|
||||
void fixed_bitmap_shutdown(void);
|
||||
#endif
|
||||
|
||||
#ifdef EINA_STATIC_BUILD_ONE_BIG
|
||||
Eina_Bool one_big_init(void);
|
||||
void one_big_shutdown(void);
|
||||
|
@ -235,21 +215,9 @@ eina_mempool_init(void)
|
|||
eina_module_list_load(_modules);
|
||||
|
||||
/* builtin backends */
|
||||
#ifdef EINA_STATIC_BUILD_BUDDY
|
||||
buddy_init();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
|
||||
chained_init();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
ememoa_fixed_init();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
ememoa_unknown_init();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
fixed_bitmap_init();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_ONE_BIG
|
||||
one_big_init();
|
||||
#endif
|
||||
|
@ -270,21 +238,9 @@ Eina_Bool
|
|||
eina_mempool_shutdown(void)
|
||||
{
|
||||
/* builtin backends */
|
||||
#ifdef EINA_STATIC_BUILD_BUDDY
|
||||
buddy_shutdown();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_CHAINED_POOL
|
||||
chained_shutdown();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
ememoa_fixed_shutdown();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
ememoa_unknown_shutdown();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
fixed_bitmap_shutdown();
|
||||
#endif
|
||||
#ifdef EINA_STATIC_BUILD_ONE_BIG
|
||||
one_big_shutdown();
|
||||
#endif
|
||||
|
|
|
@ -31,25 +31,11 @@
|
|||
*
|
||||
* Several mempool are available:
|
||||
*
|
||||
* @li @c buddy: It uses the
|
||||
* <a href="http://en.wikipedia.org/wiki/Buddy_memory_allocation">"buddy
|
||||
* allocator" algorithm</a> but the Eina implementation differs in the
|
||||
* sense that the chunk information is not stored on the chunk itself,
|
||||
* but on another memory area. This is useful for cases where the
|
||||
* memory to manage might be slower to access, or limited (like video
|
||||
* memory).
|
||||
* @li @c chained_pool: It is the default one. It allocates a big
|
||||
* chunk of memory with malloc() and split the result in chunks of the
|
||||
* requested size that are pushed inside a stack. When requested, it
|
||||
* takes this pointer from the stack to give them to whoever wants
|
||||
* them.
|
||||
* @li @c ememoa_fixed and @c ememoa_unknown: experimental allocators
|
||||
* which could be useful when a fixed amount of memory is needed.
|
||||
* @li @c fixed_bitmap: It allocates with malloc) 32* the requested
|
||||
* size and push the pool pointer in an rbtree. To find empty space in
|
||||
* a pool, it will just search for the first bit set in an int (32
|
||||
* bits). Then, when a pointer is freed, it will do a search inside
|
||||
* the rbtree.
|
||||
* @li @c pass_through: it just call malloc() and free(). It may be
|
||||
* faster on some computers than using our own allocators (like having
|
||||
* a huge L2 cache, over 4MB).
|
||||
|
|
|
@ -2,36 +2,12 @@ MAINTAINERCLEANFILES = Makefile.in
|
|||
|
||||
SUBDIRS =
|
||||
|
||||
if EINA_BUILD_BUDDY
|
||||
if !EINA_STATIC_BUILD_BUDDY
|
||||
SUBDIRS += buddy
|
||||
endif
|
||||
endif
|
||||
|
||||
if EINA_BUILD_CHAINED_POOL
|
||||
if !EINA_STATIC_BUILD_CHAINED_POOL
|
||||
SUBDIRS += chained_pool
|
||||
endif
|
||||
endif
|
||||
|
||||
if EINA_BUILD_EMEMOA_FIXED
|
||||
if !EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
SUBDIRS += ememoa_fixed
|
||||
endif
|
||||
endif
|
||||
|
||||
if EINA_BUILD_EMEMOA_UNKNOWN
|
||||
if !EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
SUBDIRS += ememoa_unknown
|
||||
endif
|
||||
endif
|
||||
|
||||
if EINA_BUILD_FIXED_BITMAP
|
||||
if !EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
SUBDIRS += fixed_bitmap
|
||||
endif
|
||||
endif
|
||||
|
||||
if EINA_BUILD_ONE_BIG
|
||||
if !EINA_STATIC_BUILD_ONE_BIG
|
||||
SUBDIRS += one_big
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I. \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
@EFL_EINA_BUILD@
|
||||
|
||||
controllerdir = $(libdir)/eina/modules/mp/buddy/$(MODULE_ARCH)
|
||||
controller_LTLIBRARIES = module.la
|
||||
|
||||
module_la_SOURCES = eina_buddy.c
|
||||
|
||||
module_la_CFLAGS = @EINA_CFLAGS@
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
|
||||
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||
module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
install-data-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
|
||||
uninstall-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/module.*
|
||||
|
||||
clean-local:
|
||||
rm -rf *.gcno
|
|
@ -1,292 +0,0 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2009 Jorge Luis Zapata Muga
|
||||
*
|
||||
* This library 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 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a naive 'buddy' allocator following Knuth's documentation.
|
||||
* The main difference is that we dont store the block information
|
||||
* on the block memory itself but on another malloc'd area.
|
||||
* This is useful for managing memory which isn't as fast as the main
|
||||
* memory like the video memory
|
||||
* The algorithm uses an area to store the linked list of blocks.
|
||||
* Each block size is equal to the minimum allocatable block size for
|
||||
* the memory pool and the number of blocks is equal to the size of the
|
||||
* memory pool divided by the block size.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eina_types.h"
|
||||
#include "eina_inlist.h"
|
||||
#include "eina_module.h"
|
||||
#include "eina_mempool.h"
|
||||
#include "eina_private.h"
|
||||
|
||||
typedef struct _Block
|
||||
{
|
||||
EINA_INLIST;
|
||||
Eina_Bool available : 1;
|
||||
unsigned short int order : 7; /* final order is order + min_order */
|
||||
} Block;
|
||||
|
||||
typedef struct _Buddy
|
||||
{
|
||||
void *heap; /* start address of the heap */
|
||||
size_t size; /* total size in bytes of the heap */
|
||||
unsigned int min_order; /* minimum size is 1 << min_order */
|
||||
unsigned int max_order; /* maximum size is 1 << max_order */
|
||||
unsigned int num_order; /* number of orders */
|
||||
Eina_Inlist **areas; /* one area per order */
|
||||
Block *blocks; /* the allocated block information */
|
||||
} Buddy;
|
||||
|
||||
/* get the minimum order greater or equal to size */
|
||||
static inline unsigned int _get_order(Buddy *b, size_t size)
|
||||
{
|
||||
unsigned int i;
|
||||
size_t bytes;
|
||||
|
||||
bytes = 1 << b->min_order;
|
||||
for (i = 0; bytes < size && i < b->num_order; i++)
|
||||
{
|
||||
bytes += bytes;
|
||||
}
|
||||
//printf("order for size %d is %d\n", size, i + b->min_order);
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline void *_get_offset(Buddy *b, Block *block)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = (char *)b->heap + ((block - &b->blocks[0]) << b->min_order);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *_init(EINA_UNUSED const char *context,
|
||||
EINA_UNUSED const char *options,
|
||||
va_list args)
|
||||
{
|
||||
Buddy *b;
|
||||
int i;
|
||||
size_t bytes;
|
||||
size_t size;
|
||||
size_t min_order;
|
||||
void *heap;
|
||||
|
||||
heap = va_arg(args, void *);
|
||||
size = va_arg(args, size_t);
|
||||
min_order = va_arg(args, int);
|
||||
/* the minimum order we support is 15 (32K) */
|
||||
min_order = min_order < 15 ? 15 : min_order;
|
||||
bytes = 1 << min_order;
|
||||
for (i = 0; bytes <= size; i++)
|
||||
{
|
||||
bytes += bytes;
|
||||
}
|
||||
if (!i)
|
||||
return NULL;
|
||||
|
||||
b = malloc(sizeof(Buddy));
|
||||
b->heap = heap;
|
||||
b->size = size;
|
||||
b->min_order = min_order;
|
||||
b->max_order = min_order + i - 1;
|
||||
b->num_order = i;
|
||||
b->areas = calloc(b->num_order, sizeof(Eina_Inlist *));
|
||||
b->blocks = calloc(1 << (b->num_order - 1), sizeof(Block));
|
||||
/* setup the initial free area */
|
||||
b->blocks[0].available = EINA_TRUE;
|
||||
b->areas[b->num_order - 1] = EINA_INLIST_GET(&(b->blocks[0]));
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static void _shutdown(void *data)
|
||||
{
|
||||
Buddy *b = data;
|
||||
|
||||
free(b->blocks);
|
||||
free(b->areas);
|
||||
free(b);
|
||||
}
|
||||
|
||||
static void _free(void *data, void *element)
|
||||
{
|
||||
Buddy *b = data;
|
||||
Block *block, *buddy;
|
||||
size_t offset;
|
||||
size_t idx;
|
||||
|
||||
offset = (unsigned char *)element - (unsigned char *)b->heap;
|
||||
if (offset > b->size)
|
||||
return;
|
||||
|
||||
idx = offset >> b->min_order;
|
||||
block = &b->blocks[idx];
|
||||
|
||||
//printf("free %x idx = %d order = %d buddy = %d\n", offset, idx, block->order, idx ^ (1 << block->order));
|
||||
/* we should always work with the buddy at right */
|
||||
if (idx & (1 << block->order))
|
||||
{
|
||||
Block *left;
|
||||
|
||||
idx = idx ^ (1 << block->order);
|
||||
left = &b->blocks[idx];
|
||||
if (!left->available)
|
||||
goto end;
|
||||
else
|
||||
{
|
||||
buddy = block;
|
||||
block = left;
|
||||
b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
|
||||
EINA_INLIST_GET(block));
|
||||
block->order++;
|
||||
}
|
||||
}
|
||||
|
||||
check:
|
||||
/* already on the last order */
|
||||
if (block->order + b->min_order == b->max_order)
|
||||
{
|
||||
goto end; /* get the buddy */
|
||||
|
||||
}
|
||||
|
||||
buddy = &b->blocks[idx ^ (1 << block->order)];
|
||||
if (!buddy->available)
|
||||
{
|
||||
goto end; /* merge two blocks */
|
||||
|
||||
}
|
||||
|
||||
b->areas[block->order] = eina_inlist_remove(b->areas[block->order],
|
||||
EINA_INLIST_GET(buddy));
|
||||
block->order++;
|
||||
goto check;
|
||||
end:
|
||||
/* add the block to the free list */
|
||||
block->available = EINA_TRUE;
|
||||
b->areas[block->order] = eina_inlist_append(b->areas[block->order],
|
||||
EINA_INLIST_GET(block));
|
||||
}
|
||||
|
||||
static void *_alloc(void *data, unsigned int size)
|
||||
{
|
||||
Buddy *b = data;
|
||||
Block *block, *buddy;
|
||||
unsigned int k, j;
|
||||
|
||||
k = j = _get_order(b, size);
|
||||
/* get a free list of order k where k <= j <= max_order */
|
||||
while ((j < b->num_order) && !b->areas[j])
|
||||
j++;
|
||||
/* check that the order is on our range */
|
||||
if (j + b->min_order > b->max_order)
|
||||
return NULL;
|
||||
|
||||
/* get a free element on this order, if not, go splitting until we find one */
|
||||
//printf("getting order %d (%d) for size %d\n", j, k, size);
|
||||
found:
|
||||
if (j == k)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
|
||||
block->available = EINA_FALSE;
|
||||
block->order = j;
|
||||
/* remove the block from the list */
|
||||
b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
|
||||
ret = _get_offset(b, block);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
block = EINA_INLIST_CONTAINER_GET(b->areas[j], Block);
|
||||
/* split */
|
||||
b->areas[j] = eina_inlist_remove(b->areas[j], EINA_INLIST_GET(block));
|
||||
j--;
|
||||
b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(block));
|
||||
buddy = block + (1 << j);
|
||||
buddy->order = j;
|
||||
buddy->available = EINA_TRUE;
|
||||
b->areas[j] = eina_inlist_append(b->areas[j], EINA_INLIST_GET(buddy));
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
static void _statistics(void *data)
|
||||
{
|
||||
Buddy *b = data;
|
||||
unsigned int i;
|
||||
|
||||
printf("Information:\n");
|
||||
printf(
|
||||
"size = %zu, min_order = %d, max_order = %d, num_order = %d, num_blocks = %d (%uKB)\n",
|
||||
b->size,
|
||||
b->min_order,
|
||||
b->max_order,
|
||||
b->num_order,
|
||||
1 << b->num_order,
|
||||
((1 << (b->num_order)) * sizeof(Block)) / 1024);
|
||||
printf("Area dumping:");
|
||||
/* iterate over the free lists and dump the maps */
|
||||
for (i = 0; i < b->num_order; i++)
|
||||
{
|
||||
Block *block;
|
||||
|
||||
printf("\n2^%d:", b->min_order + i);
|
||||
EINA_INLIST_FOREACH(b->areas[i], block)
|
||||
{
|
||||
printf(" %d", (block - &b->blocks[0]));
|
||||
}
|
||||
}
|
||||
printf("\nBlocks dumping:\n");
|
||||
}
|
||||
|
||||
static Eina_Mempool_Backend _backend = {
|
||||
"buddy",
|
||||
&_init,
|
||||
&_free,
|
||||
&_alloc,
|
||||
NULL, /* realloc */
|
||||
NULL, /* garbage collect */
|
||||
&_statistics,
|
||||
&_shutdown,
|
||||
NULL /* repack */
|
||||
};
|
||||
|
||||
Eina_Bool buddy_init(void)
|
||||
{
|
||||
return eina_mempool_register(&_backend);
|
||||
}
|
||||
|
||||
void buddy_shutdown(void)
|
||||
{
|
||||
eina_mempool_unregister(&_backend);
|
||||
}
|
||||
|
||||
|
||||
#ifndef EINA_STATIC_BUILD_BUDDY
|
||||
|
||||
EINA_MODULE_INIT(buddy_init);
|
||||
EINA_MODULE_SHUTDOWN(buddy_shutdown);
|
||||
|
||||
#endif /* ! EINA_STATIC_BUILD_BUDDY */
|
|
@ -1,28 +0,0 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I. \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
@EMEMOA_CFLAGS@ \
|
||||
@EFL_EINA_BUILD@
|
||||
|
||||
controllerdir = $(libdir)/eina/modules/mp/ememoa_fixed/$(MODULE_ARCH)
|
||||
controller_LTLIBRARIES = module.la
|
||||
|
||||
module_la_SOURCES = eina_ememoa_fixed.c
|
||||
|
||||
module_la_CFLAGS = @EINA_CFLAGS@
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
|
||||
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||
module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
install-data-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
|
||||
uninstall-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/module.*
|
||||
|
||||
clean-local:
|
||||
rm -rf *.gcno
|
|
@ -1,176 +0,0 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2008 Cedric BAIL
|
||||
*
|
||||
* This library 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 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ememoa_mempool_fixed.h>
|
||||
|
||||
#include "eina_inlist.h"
|
||||
#include "eina_error.h"
|
||||
#include "eina_module.h"
|
||||
#include "eina_mempool.h"
|
||||
|
||||
#include "eina_private.h"
|
||||
|
||||
typedef struct _Eina_Ememoa_Fixed_Mempool Eina_Ememoa_Fixed_Mempool;
|
||||
struct _Eina_Ememoa_Fixed_Mempool
|
||||
{
|
||||
struct ememoa_mempool_desc_s *desc;
|
||||
int pool;
|
||||
};
|
||||
|
||||
static void *
|
||||
eina_ememoa_fixed_malloc(void *data, EINA_UNUSED unsigned int size)
|
||||
{
|
||||
Eina_Ememoa_Fixed_Mempool *efm = data;
|
||||
|
||||
return ememoa_mempool_fixed_pop_object(efm->pool);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_fixed_free(void *data, void *ptr)
|
||||
{
|
||||
Eina_Ememoa_Fixed_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_fixed_push_object(efm->pool, ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_ememoa_fixed_realloc(EINA_UNUSED void *data,
|
||||
EINA_UNUSED void *element,
|
||||
EINA_UNUSED unsigned int size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_fixed_gc(void *data)
|
||||
{
|
||||
Eina_Ememoa_Fixed_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_fixed_garbage_collect(efm->pool);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_fixed_statistics(void *data)
|
||||
{
|
||||
Eina_Ememoa_Fixed_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_fixed_display_statistic(efm->pool);
|
||||
(void)efm;
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_ememoa_fixed_init(const char *context,
|
||||
EINA_UNUSED const char *option,
|
||||
va_list args)
|
||||
{
|
||||
struct ememoa_mempool_desc_s *desc = NULL;
|
||||
Eina_Ememoa_Fixed_Mempool *efm = NULL;
|
||||
Eina_Bool thread_protect;
|
||||
int context_length;
|
||||
int item_size;
|
||||
int pool_size;
|
||||
|
||||
if (context)
|
||||
{
|
||||
context_length = strlen(context) + 1;
|
||||
|
||||
desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
|
||||
if (!desc)
|
||||
goto on_error;
|
||||
|
||||
desc->name = (char *)(desc + 1);
|
||||
memcpy((char *)desc->name, context, context_length);
|
||||
}
|
||||
|
||||
item_size = va_arg(args, int);
|
||||
pool_size = va_arg(args, int);
|
||||
thread_protect = va_arg(args, int);
|
||||
|
||||
efm = malloc(sizeof (Eina_Ememoa_Fixed_Mempool));
|
||||
if (!efm)
|
||||
goto on_error;
|
||||
|
||||
efm->desc = desc;
|
||||
efm->pool = ememoa_mempool_fixed_init(
|
||||
item_size,
|
||||
pool_size,
|
||||
thread_protect ?
|
||||
EMEMOA_THREAD_PROTECTION : 0,
|
||||
efm->desc);
|
||||
if (efm->pool < 0)
|
||||
goto on_error;
|
||||
|
||||
return efm;
|
||||
|
||||
on_error:
|
||||
if (desc)
|
||||
free(desc);
|
||||
|
||||
if (efm)
|
||||
free(efm);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_fixed_shutdown(void *data)
|
||||
{
|
||||
Eina_Ememoa_Fixed_Mempool *efm = data;
|
||||
|
||||
if (efm->desc)
|
||||
free(efm->desc);
|
||||
|
||||
ememoa_mempool_fixed_clean(efm->pool);
|
||||
free(efm);
|
||||
}
|
||||
|
||||
static Eina_Mempool_Backend _eina_ememoa_mp_backend = {
|
||||
.name = "ememoa_fixed",
|
||||
.init = &eina_ememoa_fixed_init,
|
||||
.shutdown = &eina_ememoa_fixed_shutdown,
|
||||
.realloc = &eina_ememoa_fixed_realloc,
|
||||
.alloc = &eina_ememoa_fixed_malloc,
|
||||
.free = &eina_ememoa_fixed_free,
|
||||
.garbage_collect = &eina_ememoa_fixed_gc,
|
||||
.statistics = &eina_ememoa_fixed_statistics,
|
||||
.repack = NULL
|
||||
};
|
||||
|
||||
Eina_Bool ememoa_fixed_init(void)
|
||||
{
|
||||
return eina_mempool_register(&_eina_ememoa_mp_backend);
|
||||
}
|
||||
|
||||
void ememoa_fixed_shutdown(void)
|
||||
{
|
||||
eina_mempool_unregister(&_eina_ememoa_mp_backend);
|
||||
}
|
||||
|
||||
|
||||
#ifndef EINA_STATIC_BUILD_EMEMOA_FIXED
|
||||
|
||||
EINA_MODULE_INIT(ememoa_fixed_init);
|
||||
EINA_MODULE_SHUTDOWN(ememoa_fixed_shutdown);
|
||||
|
||||
#endif /* ! EINA_STATIC_BUILD_EMEMOA_FIXED */
|
|
@ -1,28 +0,0 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I. \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
@EMEMOA_CFLAGS@ \
|
||||
@EFL_EINA_BUILD@
|
||||
|
||||
controllerdir = $(libdir)/eina/modules/mp/ememoa_unknown/$(MODULE_ARCH)
|
||||
controller_LTLIBRARIES = module.la
|
||||
|
||||
module_la_SOURCES = eina_ememoa_unknown.c
|
||||
|
||||
module_la_CFLAGS = @EINA_CFLAGS@
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EMEMOA_LIBS@ @EINA_LIBS@
|
||||
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||
module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
install-data-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
|
||||
uninstall-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/module.*
|
||||
|
||||
clean-local:
|
||||
rm -rf *.gcno
|
|
@ -1,182 +0,0 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2008 Cedric BAIL
|
||||
*
|
||||
* This library 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 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ememoa_mempool_fixed.h>
|
||||
#include <ememoa_mempool_unknown_size.h>
|
||||
|
||||
#include "eina_types.h"
|
||||
#include "eina_module.h"
|
||||
#include "eina_private.h"
|
||||
#include "eina_mempool.h"
|
||||
|
||||
typedef struct _Eina_Ememoa_Unknown_Size_Mempool
|
||||
Eina_Ememoa_Unknown_Size_Mempool;
|
||||
struct _Eina_Ememoa_Unknown_Size_Mempool
|
||||
{
|
||||
struct ememoa_mempool_desc_s *desc;
|
||||
int pool;
|
||||
};
|
||||
|
||||
static void *
|
||||
eina_ememoa_unknown_size_malloc(void *data, unsigned int size)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
return ememoa_mempool_unknown_size_pop_object(efm->pool, size);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_unknown_size_free(void *data, void *ptr)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_unknown_size_push_object(efm->pool, ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_ememoa_unknown_size_realloc(void *data, void *element, unsigned int size)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
return ememoa_mempool_unknown_size_resize_object(efm->pool, element, size);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_unknown_size_gc(void *data)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_unknown_size_garbage_collect(efm->pool);
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_unknown_size_statistics(void *data)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
ememoa_mempool_unknown_size_display_statistic(efm->pool);
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_ememoa_unknown_size_init(const char *context,
|
||||
EINA_UNUSED const char *option,
|
||||
va_list args)
|
||||
{
|
||||
struct ememoa_mempool_desc_s *desc = NULL;
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = NULL;
|
||||
Eina_Bool thread_protect;
|
||||
unsigned int *items_map = NULL;
|
||||
unsigned int items_count;
|
||||
unsigned int i;
|
||||
int context_length;
|
||||
|
||||
if (context)
|
||||
{
|
||||
context_length = strlen(context) + 1;
|
||||
|
||||
desc = calloc(1, sizeof (struct ememoa_mempool_desc_s) + context_length);
|
||||
if (!desc)
|
||||
goto on_error;
|
||||
|
||||
desc->name = (char *)(desc + 1);
|
||||
memcpy((char *)desc->name, context, context_length);
|
||||
}
|
||||
|
||||
thread_protect = va_arg(args, int);
|
||||
items_count = va_arg(args, unsigned int);
|
||||
|
||||
items_map = malloc(sizeof (unsigned int) * 2 * items_count);
|
||||
|
||||
for (i = 0; i < (items_count << 1); ++i)
|
||||
items_map[i] = va_arg(args, unsigned int);
|
||||
|
||||
efm = malloc(sizeof (Eina_Ememoa_Unknown_Size_Mempool));
|
||||
if (!efm)
|
||||
goto on_error;
|
||||
|
||||
efm->desc = desc;
|
||||
efm->pool = ememoa_mempool_unknown_size_init(
|
||||
items_count,
|
||||
items_map,
|
||||
thread_protect ?
|
||||
EMEMOA_THREAD_PROTECTION : 0,
|
||||
efm->desc);
|
||||
if (efm->pool < 0)
|
||||
goto on_error;
|
||||
|
||||
return efm;
|
||||
|
||||
on_error:
|
||||
if (items_map)
|
||||
free(items_map);
|
||||
|
||||
if (desc)
|
||||
free(desc);
|
||||
|
||||
if (efm)
|
||||
free(efm);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
eina_ememoa_unknown_size_shutdown(void *data)
|
||||
{
|
||||
Eina_Ememoa_Unknown_Size_Mempool *efm = data;
|
||||
|
||||
if (efm->desc)
|
||||
free(efm->desc);
|
||||
|
||||
ememoa_mempool_unknown_size_clean(efm->pool);
|
||||
free(efm);
|
||||
}
|
||||
|
||||
static Eina_Mempool_Backend _eina_ememoa_unknown_mp_backend = {
|
||||
.name = "ememoa_unknown",
|
||||
.init = &eina_ememoa_unknown_size_init,
|
||||
.shutdown = &eina_ememoa_unknown_size_shutdown,
|
||||
.realloc = &eina_ememoa_unknown_size_realloc,
|
||||
.alloc = &eina_ememoa_unknown_size_malloc,
|
||||
.free = &eina_ememoa_unknown_size_free,
|
||||
.garbage_collect = &eina_ememoa_unknown_size_gc,
|
||||
.statistics = &eina_ememoa_unknown_size_statistics,
|
||||
.repack = NULL
|
||||
};
|
||||
|
||||
Eina_Bool ememoa_unknown_init(void)
|
||||
{
|
||||
return eina_mempool_register(&_eina_ememoa_unknown_mp_backend);
|
||||
}
|
||||
|
||||
void ememoa_unknown_shutdown(void)
|
||||
{
|
||||
eina_mempool_unregister(&_eina_ememoa_unknown_mp_backend);
|
||||
}
|
||||
|
||||
#ifndef EINA_STATIC_BUILD_EMEMOA_UNKNOWN
|
||||
|
||||
EINA_MODULE_INIT(ememoa_unknown_init);
|
||||
EINA_MODULE_SHUTDOWN(ememoa_unknown_shutdown);
|
||||
|
||||
#endif /* ! EINA_STATIC_BUILD_EMEMOA_UNKNOWN */
|
|
@ -1,27 +0,0 @@
|
|||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I. \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
-I$(top_srcdir)/src/lib/eina \
|
||||
-I$(top_builddir)/src/lib/eina \
|
||||
@EFL_EINA_BUILD@
|
||||
|
||||
controllerdir = $(libdir)/eina/modules/mp/fixed_bitmap/$(MODULE_ARCH)
|
||||
controller_LTLIBRARIES = module.la
|
||||
|
||||
module_la_SOURCES = eina_fixed_bitmap.c
|
||||
|
||||
module_la_CFLAGS = @EINA_CFLAGS@
|
||||
module_la_LIBADD = $(top_builddir)/src/lib/eina/libeina.la @EINA_LIBS@
|
||||
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||
module_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
install-data-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/$(controller_LTLIBRARIES)
|
||||
uninstall-hook:
|
||||
rm -f $(DESTDIR)$(controllerdir)/module.*
|
||||
|
||||
clean-local:
|
||||
rm -rf *.gcno
|
|
@ -1,270 +0,0 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2008 Cedric BAIL
|
||||
*
|
||||
* This library 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 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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 this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_EVIL
|
||||
# include <Evil.h>
|
||||
#endif
|
||||
|
||||
#include "eina_inlist.h"
|
||||
#include "eina_rbtree.h"
|
||||
#include "eina_error.h"
|
||||
|
||||
#include "eina_mempool.h"
|
||||
|
||||
#include "eina_private.h"
|
||||
|
||||
typedef struct _Eina_Fixed_Bitmap Eina_Fixed_Bitmap;
|
||||
typedef struct _Eina_Fixed_Bitmap_Pool Eina_Fixed_Bitmap_Pool;
|
||||
|
||||
struct _Eina_Fixed_Bitmap
|
||||
{
|
||||
Eina_Rbtree *lookup;
|
||||
Eina_Inlist *head;
|
||||
|
||||
int item_size;
|
||||
};
|
||||
|
||||
struct _Eina_Fixed_Bitmap_Pool
|
||||
{
|
||||
EINA_RBTREE;
|
||||
EINA_INLIST;
|
||||
|
||||
uint32_t bitmask;
|
||||
};
|
||||
|
||||
static inline size_t
|
||||
_eina_rbtree_inlist_delta(void)
|
||||
{
|
||||
Eina_Fixed_Bitmap_Pool tmp;
|
||||
void *a = &tmp.__rbtree;
|
||||
void *b = &tmp.__in_list;
|
||||
|
||||
return (char *)a - (char *)b;
|
||||
}
|
||||
|
||||
static Eina_Rbtree_Direction
|
||||
_eina_fixed_cmp(const Eina_Rbtree *left,
|
||||
const Eina_Rbtree *right,
|
||||
EINA_UNUSED void *data)
|
||||
{
|
||||
if (left - right < 0)
|
||||
return EINA_RBTREE_LEFT;
|
||||
|
||||
return EINA_RBTREE_RIGHT;
|
||||
}
|
||||
|
||||
static int
|
||||
_eina_fixed_cmp_key(const Eina_Rbtree *node,
|
||||
const void *key,
|
||||
EINA_UNUSED int length,
|
||||
Eina_Fixed_Bitmap *mp)
|
||||
{
|
||||
const void *a = node;
|
||||
const void *b = key;
|
||||
ssize_t delta;
|
||||
ssize_t limit;
|
||||
|
||||
limit = sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32;
|
||||
delta = (char *)a - (char *)b;
|
||||
|
||||
if (delta > 0)
|
||||
return 1;
|
||||
|
||||
if (delta + limit < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_eina_fixed_bitmap_pool_free(Eina_Fixed_Bitmap_Pool *pool,
|
||||
EINA_UNUSED void *data)
|
||||
{
|
||||
free(pool);
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_fixed_bitmap_malloc(void *data, EINA_UNUSED unsigned int size)
|
||||
{
|
||||
Eina_Fixed_Bitmap *mp = data;
|
||||
Eina_Fixed_Bitmap_Pool *pool = NULL;
|
||||
void *ptr;
|
||||
int idx;
|
||||
|
||||
if (mp->head)
|
||||
{
|
||||
pool =
|
||||
(Eina_Fixed_Bitmap_Pool *)((unsigned char *)mp->head +
|
||||
_eina_rbtree_inlist_delta());
|
||||
|
||||
if (pool->bitmask == 0)
|
||||
pool = NULL;
|
||||
}
|
||||
|
||||
if (!pool)
|
||||
{
|
||||
eina_error_set(0);
|
||||
pool = malloc(sizeof (Eina_Fixed_Bitmap_Pool) + mp->item_size * 32);
|
||||
if (!pool)
|
||||
{
|
||||
eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pool->bitmask = 0xFFFFFFFF;
|
||||
|
||||
mp->head = eina_inlist_prepend(mp->head, EINA_INLIST_GET(pool));
|
||||
mp->lookup = eina_rbtree_inline_insert(mp->lookup, EINA_RBTREE_GET(
|
||||
pool),
|
||||
EINA_RBTREE_CMP_NODE_CB(
|
||||
_eina_fixed_cmp), NULL);
|
||||
}
|
||||
|
||||
idx = ffs(pool->bitmask) - 1;
|
||||
pool->bitmask &= ~(1 << idx);
|
||||
ptr = (unsigned char *)(pool + 1) + idx * mp->item_size;
|
||||
|
||||
if (pool->bitmask == 0)
|
||||
mp->head = eina_inlist_demote(mp->head, EINA_INLIST_GET(pool));
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
eina_fixed_bitmap_free(void *data, void *ptr)
|
||||
{
|
||||
Eina_Fixed_Bitmap *mp = data;
|
||||
Eina_Fixed_Bitmap_Pool *pool;
|
||||
void *a;
|
||||
Eina_Bool push_front = EINA_FALSE;
|
||||
ssize_t delta;
|
||||
|
||||
pool = (Eina_Fixed_Bitmap_Pool *)eina_rbtree_inline_lookup(
|
||||
mp->lookup,
|
||||
ptr,
|
||||
0,
|
||||
EINA_RBTREE_CMP_KEY_CB(
|
||||
_eina_fixed_cmp_key),
|
||||
mp);
|
||||
if (!pool)
|
||||
return;
|
||||
|
||||
if (pool->bitmask != 0xFFFFFFFF)
|
||||
push_front = EINA_TRUE;
|
||||
|
||||
a = pool;
|
||||
delta =
|
||||
((char *)ptr - (char *)a -
|
||||
sizeof (Eina_Fixed_Bitmap_Pool)) / mp->item_size;
|
||||
|
||||
assert(delta >= 0 && delta < 32);
|
||||
|
||||
pool->bitmask |= (1 << (delta & 0x1F));
|
||||
|
||||
if (pool->bitmask == 0xFFFFFFFF)
|
||||
{
|
||||
mp->head = eina_inlist_remove(mp->head, EINA_INLIST_GET(pool));
|
||||
mp->lookup = eina_rbtree_inline_remove(mp->lookup, EINA_RBTREE_GET(
|
||||
pool),
|
||||
EINA_RBTREE_CMP_NODE_CB(
|
||||
_eina_fixed_cmp), NULL);
|
||||
free(pool);
|
||||
}
|
||||
else if (push_front)
|
||||
mp->head = eina_inlist_promote(mp->head, EINA_INLIST_GET(pool));
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_fixed_bitmap_realloc(EINA_UNUSED void *data,
|
||||
EINA_UNUSED void *element,
|
||||
EINA_UNUSED unsigned int size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
eina_fixed_bitmap_init(EINA_UNUSED const char *context,
|
||||
EINA_UNUSED const char *option,
|
||||
va_list args)
|
||||
{
|
||||
Eina_Fixed_Bitmap *mp;
|
||||
int item_size;
|
||||
|
||||
mp = malloc(sizeof (Eina_Fixed_Bitmap));
|
||||
if (!mp)
|
||||
return NULL;
|
||||
|
||||
item_size = va_arg(args, int);
|
||||
|
||||
mp->item_size = eina_mempool_alignof(item_size);
|
||||
|
||||
mp->lookup = NULL;
|
||||
mp->head = NULL;
|
||||
|
||||
return mp;
|
||||
}
|
||||
|
||||
static void
|
||||
eina_fixed_bitmap_shutdown(void *data)
|
||||
{
|
||||
Eina_Fixed_Bitmap *mp = data;
|
||||
|
||||
eina_rbtree_delete(mp->lookup,
|
||||
EINA_RBTREE_FREE_CB(_eina_fixed_bitmap_pool_free), NULL);
|
||||
free(mp);
|
||||
}
|
||||
|
||||
static Eina_Mempool_Backend _eina_fixed_bitmap_mp_backend = {
|
||||
"fixed_bitmap",
|
||||
&eina_fixed_bitmap_init,
|
||||
&eina_fixed_bitmap_free,
|
||||
&eina_fixed_bitmap_malloc,
|
||||
&eina_fixed_bitmap_realloc,
|
||||
NULL,
|
||||
NULL,
|
||||
&eina_fixed_bitmap_shutdown,
|
||||
NULL
|
||||
};
|
||||
|
||||
Eina_Bool fixed_bitmap_init(void)
|
||||
{
|
||||
return eina_mempool_register(&_eina_fixed_bitmap_mp_backend);
|
||||
}
|
||||
|
||||
void fixed_bitmap_shutdown(void)
|
||||
{
|
||||
eina_mempool_unregister(&_eina_fixed_bitmap_mp_backend);
|
||||
}
|
||||
|
||||
#ifndef EINA_STATIC_BUILD_FIXED_BITMAP
|
||||
|
||||
EINA_MODULE_INIT(fixed_bitmap_init);
|
||||
EINA_MODULE_SHUTDOWN(fixed_bitmap_shutdown);
|
||||
|
||||
#endif /* ! EINA_STATIC_BUILD_FIXED_BITMAP */
|
||||
|
Loading…
Reference in New Issue