Adding turran work to unify EFL data types and functions.
SVN revision: 35248
This commit is contained in:
parent
e20edb01e2
commit
a92e3d6c83
|
@ -0,0 +1,2 @@
|
||||||
|
Jorge Luis "turran" Zapata <jorgeluis.zapata@gmail.com>
|
||||||
|
Carsten Haitzler <raster@rasterman.com>
|
|
@ -0,0 +1,139 @@
|
||||||
|
PROJECT_NAME = Eina
|
||||||
|
PROJECT_NUMBER =
|
||||||
|
OUTPUT_DIRECTORY = doc
|
||||||
|
INPUT = ./src/lib
|
||||||
|
IMAGE_PATH = doc/img
|
||||||
|
OUTPUT_LANGUAGE = English
|
||||||
|
GENERATE_HTML = YES
|
||||||
|
HTML_OUTPUT = html
|
||||||
|
HTML_FILE_EXTENSION = .html
|
||||||
|
HTML_HEADER =
|
||||||
|
HTML_FOOTER =
|
||||||
|
HTML_STYLESHEET =
|
||||||
|
HTML_ALIGN_MEMBERS = YES
|
||||||
|
ENUM_VALUES_PER_LINE = 1
|
||||||
|
GENERATE_HTMLHELP = NO
|
||||||
|
CHM_FILE =
|
||||||
|
HHC_LOCATION =
|
||||||
|
GENERATE_CHI = NO
|
||||||
|
BINARY_TOC = NO
|
||||||
|
TOC_EXPAND = NO
|
||||||
|
DISABLE_INDEX = NO
|
||||||
|
EXTRACT_ALL = NO
|
||||||
|
EXTRACT_PRIVATE = NO
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = NO
|
||||||
|
HIDE_UNDOC_MEMBERS = YES
|
||||||
|
HIDE_UNDOC_CLASSES = YES
|
||||||
|
HIDE_FRIEND_COMPOUNDS = YES
|
||||||
|
BRIEF_MEMBER_DESC = YES
|
||||||
|
REPEAT_BRIEF = YES
|
||||||
|
ALWAYS_DETAILED_SEC = NO
|
||||||
|
INLINE_INHERITED_MEMB = NO
|
||||||
|
FULL_PATH_NAMES = NO
|
||||||
|
STRIP_FROM_PATH =
|
||||||
|
INTERNAL_DOCS = NO
|
||||||
|
STRIP_CODE_COMMENTS = YES
|
||||||
|
CASE_SENSE_NAMES = YES
|
||||||
|
SHORT_NAMES = NO
|
||||||
|
HIDE_SCOPE_NAMES = NO
|
||||||
|
VERBATIM_HEADERS = NO
|
||||||
|
SHOW_INCLUDE_FILES = NO
|
||||||
|
JAVADOC_AUTOBRIEF = YES
|
||||||
|
MULTILINE_CPP_IS_BRIEF = NO
|
||||||
|
DETAILS_AT_TOP = NO
|
||||||
|
INHERIT_DOCS = YES
|
||||||
|
INLINE_INFO = YES
|
||||||
|
SORT_MEMBER_DOCS = YES
|
||||||
|
DISTRIBUTE_GROUP_DOC = NO
|
||||||
|
TAB_SIZE = 2
|
||||||
|
GENERATE_TODOLIST = YES
|
||||||
|
GENERATE_TESTLIST = YES
|
||||||
|
GENERATE_BUGLIST = YES
|
||||||
|
GENERATE_DEPRECATEDLIST= YES
|
||||||
|
ALIASES =
|
||||||
|
ENABLED_SECTIONS =
|
||||||
|
MAX_INITIALIZER_LINES = 30
|
||||||
|
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
|
OPTIMIZE_OUTPUT_JAVA = NO
|
||||||
|
SHOW_USED_FILES = NO
|
||||||
|
QUIET = YES
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = YES
|
||||||
|
WARN_FORMAT = "$file:$line: $text"
|
||||||
|
WARN_LOGFILE =
|
||||||
|
FILE_PATTERNS =
|
||||||
|
RECURSIVE = YES
|
||||||
|
EXCLUDE =
|
||||||
|
EXCLUDE_SYMLINKS = NO
|
||||||
|
EXCLUDE_PATTERNS =
|
||||||
|
EXAMPLE_PATH =
|
||||||
|
EXAMPLE_PATTERNS =
|
||||||
|
EXAMPLE_RECURSIVE = NO
|
||||||
|
INPUT_FILTER =
|
||||||
|
FILTER_SOURCE_FILES = NO
|
||||||
|
SOURCE_BROWSER = NO
|
||||||
|
INLINE_SOURCES = NO
|
||||||
|
REFERENCED_BY_RELATION = YES
|
||||||
|
REFERENCES_RELATION = YES
|
||||||
|
ALPHABETICAL_INDEX = YES
|
||||||
|
COLS_IN_ALPHA_INDEX = 2
|
||||||
|
IGNORE_PREFIX =
|
||||||
|
GENERATE_TREEVIEW = NO
|
||||||
|
TREEVIEW_WIDTH = 250
|
||||||
|
GENERATE_LATEX = YES
|
||||||
|
LATEX_OUTPUT = latex
|
||||||
|
LATEX_CMD_NAME = latex
|
||||||
|
MAKEINDEX_CMD_NAME = makeindex
|
||||||
|
COMPACT_LATEX = NO
|
||||||
|
PAPER_TYPE = a4wide
|
||||||
|
EXTRA_PACKAGES =
|
||||||
|
LATEX_HEADER =
|
||||||
|
PDF_HYPERLINKS = YES
|
||||||
|
USE_PDFLATEX = NO
|
||||||
|
LATEX_BATCHMODE = NO
|
||||||
|
GENERATE_RTF = NO
|
||||||
|
RTF_OUTPUT = rtf
|
||||||
|
COMPACT_RTF = NO
|
||||||
|
RTF_HYPERLINKS = NO
|
||||||
|
RTF_STYLESHEET_FILE =
|
||||||
|
RTF_EXTENSIONS_FILE =
|
||||||
|
GENERATE_MAN = YES
|
||||||
|
MAN_OUTPUT = man
|
||||||
|
MAN_EXTENSION = .3
|
||||||
|
MAN_LINKS = YES
|
||||||
|
GENERATE_XML = NO
|
||||||
|
XML_SCHEMA =
|
||||||
|
XML_DTD =
|
||||||
|
GENERATE_AUTOGEN_DEF = NO
|
||||||
|
ENABLE_PREPROCESSING = YES
|
||||||
|
MACRO_EXPANSION = NO
|
||||||
|
EXPAND_ONLY_PREDEF = NO
|
||||||
|
SEARCH_INCLUDES = NO
|
||||||
|
INCLUDE_PATH =
|
||||||
|
INCLUDE_FILE_PATTERNS =
|
||||||
|
PREDEFINED =
|
||||||
|
EXPAND_AS_DEFINED =
|
||||||
|
SKIP_FUNCTION_MACROS = YES
|
||||||
|
TAGFILES =
|
||||||
|
GENERATE_TAGFILE =
|
||||||
|
ALLEXTERNALS = NO
|
||||||
|
EXTERNAL_GROUPS = YES
|
||||||
|
PERL_PATH = /usr/bin/perl
|
||||||
|
CLASS_DIAGRAMS = NO
|
||||||
|
HIDE_UNDOC_RELATIONS = YES
|
||||||
|
HAVE_DOT = NO
|
||||||
|
CLASS_GRAPH = NO
|
||||||
|
COLLABORATION_GRAPH = NO
|
||||||
|
TEMPLATE_RELATIONS = NO
|
||||||
|
INCLUDE_GRAPH = NO
|
||||||
|
INCLUDED_BY_GRAPH = NO
|
||||||
|
GRAPHICAL_HIERARCHY = NO
|
||||||
|
DOT_IMAGE_FORMAT = png
|
||||||
|
DOT_PATH =
|
||||||
|
DOTFILE_DIRS =
|
||||||
|
MAX_DOT_GRAPH_WIDTH = 512
|
||||||
|
MAX_DOT_GRAPH_HEIGHT = 512
|
||||||
|
GENERATE_LEGEND = YES
|
||||||
|
DOT_CLEANUP = YES
|
||||||
|
SEARCHENGINE = NO
|
|
@ -0,0 +1,32 @@
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
SUBDIRS = src
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = \
|
||||||
|
Makefile.in \
|
||||||
|
aclocal.m4 \
|
||||||
|
config.guess \
|
||||||
|
config.h.in \
|
||||||
|
config.sub \
|
||||||
|
configure \
|
||||||
|
install-sh \
|
||||||
|
ltconfig \
|
||||||
|
ltmain.sh \
|
||||||
|
missing mkinstalldirs \
|
||||||
|
stamp-h.in \
|
||||||
|
build-stamp \
|
||||||
|
configure-stamp \
|
||||||
|
depcomp \
|
||||||
|
eina.pc \
|
||||||
|
eina_docs.tar.gz
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
AUTHORS \
|
||||||
|
COPYING \
|
||||||
|
gendoc \
|
||||||
|
Doxyfile \
|
||||||
|
README \
|
||||||
|
eina.pc
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = eina.pc
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
rm -rf autom4te.cache
|
||||||
|
rm -f aclocal.m4 ltmain.sh
|
||||||
|
|
||||||
|
echo "Running aclocal..." ; aclocal $ACLOCAL_FLAGS || exit 1
|
||||||
|
echo "Running autoheader..." ; autoheader || exit 1
|
||||||
|
echo "Running autoconf..." ; autoconf || exit 1
|
||||||
|
echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
|
||||||
|
echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1
|
||||||
|
|
||||||
|
if [ -z "$NOCONFIGURE" ]; then
|
||||||
|
./configure "$@"
|
||||||
|
fi
|
|
@ -0,0 +1,92 @@
|
||||||
|
# get rid of that stupid cache mechanism
|
||||||
|
rm -f config.cache
|
||||||
|
|
||||||
|
AC_INIT(eina, 0.0.1, enlightenment-devel@lists.sourceforge.net)
|
||||||
|
AC_PREREQ(2.52)
|
||||||
|
AC_CONFIG_SRCDIR(configure.in)
|
||||||
|
AC_CANONICAL_BUILD
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
AC_ISC_POSIX
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE(1.6 dist-bzip2)
|
||||||
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
AC_LIBTOOL_WIN32_DLL
|
||||||
|
define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl
|
||||||
|
define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
VMAJ=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $1);}'`
|
||||||
|
VMIN=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $2);}'`
|
||||||
|
VMIC=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $3);}'`
|
||||||
|
SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
|
||||||
|
version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
|
||||||
|
AC_SUBST(version_info)
|
||||||
|
|
||||||
|
# Checks for programs
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# Checks for libraries
|
||||||
|
|
||||||
|
# Checks for header files
|
||||||
|
AC_HEADER_ASSERT
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_HEADER_TIME
|
||||||
|
|
||||||
|
# Checks for types
|
||||||
|
|
||||||
|
# Checks for structures
|
||||||
|
|
||||||
|
# Checks for compiler characteristics
|
||||||
|
AC_C_CONST
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
AC_PROG_CC_STDC
|
||||||
|
|
||||||
|
if ! test "${VMIC}" = "x" ; then
|
||||||
|
CFLAGS="${CFLAGS} -Wall -W -Wextra" # -Werror
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Checks for linker characteristics
|
||||||
|
lt_enable_auto_import=""
|
||||||
|
case "$host_os" in
|
||||||
|
mingw*|cegcc*)
|
||||||
|
lt_enable_auto_import="-Wl,--enable-auto-import"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_SUBST(lt_enable_auto_import)
|
||||||
|
|
||||||
|
# Checks for library functions
|
||||||
|
|
||||||
|
## Make the debug preprocessor configurable
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
eina.pc
|
||||||
|
src/Makefile
|
||||||
|
src/include/Makefile
|
||||||
|
src/lib/Makefile
|
||||||
|
src/modules/Makefile
|
||||||
|
src/modules/mm_policies/Makefile
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
## Info
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "------------------------------------------------------------------------"
|
||||||
|
echo "$PACKAGE $VERSION"
|
||||||
|
echo "------------------------------------------------------------------------"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo "Configuration Options Summary:"
|
||||||
|
echo
|
||||||
|
echo "Installation Path.........: $prefix"
|
||||||
|
echo
|
||||||
|
echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE,"
|
||||||
|
echo "and then afterwards as root (or the user who will install this), type"
|
||||||
|
echo "'make install'. Change users with 'su' or 'sudo' appropriately."
|
||||||
|
echo
|
|
@ -0,0 +1,12 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: Eina
|
||||||
|
Description: Eina
|
||||||
|
Requires:
|
||||||
|
Version: @VERSION@
|
||||||
|
Libs: -L${libdir} -leina
|
||||||
|
Libs.private: -lm -ldl
|
||||||
|
Cflags: -I${includedir} -I${includedir}/eina
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
rm -rf ./doc/html ./doc/latex ./doc/man
|
||||||
|
mkdir -p ./doc/html ./doc/latex ./doc/man 2>/dev/null
|
||||||
|
doxygen
|
||||||
|
#cp doc/img/*.png doc/html/
|
||||||
|
rm -f edata_docs.tar ecore_docs.tar.gz
|
||||||
|
tar -cvf edata_docs.tar doc/html doc/man doc/latex
|
||||||
|
gzip -9f edata_docs.tar
|
||||||
|
exit 0
|
|
@ -0,0 +1,3 @@
|
||||||
|
SUBDIRS = lib include modules
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef EINA_H_
|
||||||
|
#define EINA_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @mainpage Eina
|
||||||
|
* @file Eina.h
|
||||||
|
* @brief Contains list, hash, debugging and tree functions.
|
||||||
|
* TODO add debug functions, magic functions, etc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "eina_types.h"
|
||||||
|
#include "eina_f16p16.h"
|
||||||
|
#include "eina_rectangle.h"
|
||||||
|
#include "eina_inlist.h"
|
||||||
|
#include "eina_file.h"
|
||||||
|
#include "eina_list.h"
|
||||||
|
#include "eina_hash.h"
|
||||||
|
#include "eina_lalloc.h"
|
||||||
|
#include "eina_module.h"
|
||||||
|
#include "eina_mempool.h"
|
||||||
|
#include "eina_error.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EINA_H */
|
|
@ -0,0 +1,20 @@
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
|
EINAHEADERS = \
|
||||||
|
eina_error.h \
|
||||||
|
eina_f16p16.h \
|
||||||
|
eina_hash.h \
|
||||||
|
eina_lalloc.h \
|
||||||
|
eina_inlist.h \
|
||||||
|
eina_list.h \
|
||||||
|
eina_file.h \
|
||||||
|
eina_mempool.h \
|
||||||
|
eina_module.h \
|
||||||
|
eina_rectangle.h \
|
||||||
|
eina_types.h
|
||||||
|
|
||||||
|
include_HEADERS = \
|
||||||
|
Eina.h
|
||||||
|
|
||||||
|
installed_headersdir = $(prefix)/include/eina
|
||||||
|
installed_headers_DATA = $(EINAHEADERS)
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef EINA_ERROR_H_
|
||||||
|
#define EINA_ERROR_H_
|
||||||
|
|
||||||
|
#define EINA_ERROR_PERR(fmt, ...) \
|
||||||
|
eina_error_print(EINA_ERROR_LEVEL_ERR, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define EINA_ERROR_PINFO(fmt, ...) \
|
||||||
|
eina_error_print(EINA_ERROR_LEVEL_INFO, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define EINA_ERROR_PWARN(fmt, ...) \
|
||||||
|
eina_error_print(EINA_ERROR_LEVEL_WARN, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define EINA_ERROR_PDBG(fmt, ...) \
|
||||||
|
eina_error_print(EINA_ERROR_LEVEL_DBG, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
typedef enum _Eina_Error_Level
|
||||||
|
{
|
||||||
|
EINA_ERROR_LEVEL_ERR,
|
||||||
|
EINA_ERROR_LEVEL_WARN,
|
||||||
|
EINA_ERROR_LEVEL_INFO,
|
||||||
|
EINA_ERROR_LEVEL_DBG,
|
||||||
|
EINA_ERROR_LEVELS
|
||||||
|
} Eina_Error_Level;
|
||||||
|
|
||||||
|
EAPI int eina_error_init(void);
|
||||||
|
EAPI int eina_error_shutdown(void);
|
||||||
|
EAPI int eina_error_register(const char *msg);
|
||||||
|
EAPI const char * eina_error_msg_get(int error);
|
||||||
|
EAPI void eina_error_print(Eina_Error_Level level, const char *file,
|
||||||
|
const char *function, int line, const char *fmt, ...);
|
||||||
|
EAPI void eina_error_log_level_set(Eina_Error_Level level);
|
||||||
|
|
||||||
|
#endif /*EINA_ERROR_H_*/
|
|
@ -0,0 +1,105 @@
|
||||||
|
#ifndef EINA_F16P16_H_
|
||||||
|
#define EINA_F16P16_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
typedef int32_t Eina_F16p16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_int_from(int32_t v)
|
||||||
|
{
|
||||||
|
return v << 16;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline int32_t eina_f16p16_int_to(Eina_F16p16 v)
|
||||||
|
{
|
||||||
|
return v >> 16;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_float_from(float v)
|
||||||
|
{
|
||||||
|
Eina_F16p16 r;
|
||||||
|
r = (Eina_F16p16)(v * 65536.0 + (v < 0 ? -0.5 : 0.5));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline float eina_f16p16_float_to(Eina_F16p16 v)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
r = v / 65536.0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_add(Eina_F16p16 a, Eina_F16p16 b)
|
||||||
|
{
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_sub(Eina_F16p16 a, Eina_F16p16 b)
|
||||||
|
{
|
||||||
|
return a - b;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_mul(Eina_F16p16 a, Eina_F16p16 b)
|
||||||
|
{
|
||||||
|
return (a * b) >> 16;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_F16p16 eina_f16p16_sqrt(Eina_F16p16 a)
|
||||||
|
{
|
||||||
|
unsigned int root, remHi, remLo, testDiv, count;
|
||||||
|
|
||||||
|
root = 0; /* Clear root */
|
||||||
|
remHi = 0; /* Clear high part of partial remainder */
|
||||||
|
remLo = a; /* Get argument into low part of partial remainder */
|
||||||
|
count = (15 + (16 >> 1)); /* Load loop counter */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
remHi = (remHi << 2) | (remLo >> 30);
|
||||||
|
remLo <<= 2; /* get 2 bits of arg */
|
||||||
|
root <<= 1; /* Get ready for the next bit in the root */
|
||||||
|
testDiv = (root << 1) + 1; /* Test radical */
|
||||||
|
if (remHi >= testDiv)
|
||||||
|
{
|
||||||
|
remHi -= testDiv;
|
||||||
|
root++;
|
||||||
|
}
|
||||||
|
} while (count-- != 0);
|
||||||
|
return (root);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline unsigned int eina_f16p16_fracc_get(Eina_F16p16 v)
|
||||||
|
{
|
||||||
|
return (v & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*EINA_F16P16_H_*/
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef EINA_FILE_H_
|
||||||
|
#define EINA_FILE_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup File_Group Memory File
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void *data);
|
||||||
|
|
||||||
|
EAPI void eina_file_dir_list(const char *dir, int recursive, Eina_File_Dir_List_Cb cb, void *data);
|
||||||
|
EAPI void eina_file_path_nth_get(const char *path, int n, char **left, char **right);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /*EINA_FILE_H_*/
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef EINA_HASH_H_
|
||||||
|
#define EINA_HASH_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct _Eina_Hash Eina_Hash;
|
||||||
|
|
||||||
|
EAPI Eina_Hash *eina_hash_add (Eina_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI Eina_Hash *eina_hash_direct_add (Eina_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI Eina_Hash *eina_hash_del (Eina_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI void *eina_hash_find(const Eina_Hash *hash, const char *key);
|
||||||
|
EAPI void *eina_hash_modify(Eina_Hash *hash, const char *key, const void *data);
|
||||||
|
EAPI int eina_hash_size(const Eina_Hash *hash);
|
||||||
|
EAPI void eina_hash_free(Eina_Hash *hash);
|
||||||
|
EAPI void eina_hash_foreach(const Eina_Hash *hash, Eina_Bool (*func) (const Eina_Hash *hash, const char *key, void *data, void *fdata),
|
||||||
|
const void *fdata);
|
||||||
|
|
||||||
|
#endif /*EINA_HASH_H_*/
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef EINA_INLIST_H_
|
||||||
|
#define EINA_INLIST_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Inline_List_Group Inline List
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO change the prototype to use an Eina_Inlist */
|
||||||
|
typedef struct _Eina_Inlist Eina_Inlist;
|
||||||
|
|
||||||
|
struct _Eina_Inlist
|
||||||
|
{
|
||||||
|
Eina_Inlist *next;
|
||||||
|
Eina_Inlist *prev;
|
||||||
|
Eina_Inlist *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
EAPI void * eina_inlist_append(void *in_list, void *in_item);
|
||||||
|
EAPI void * eina_inlist_prepend(void *in_list, void *in_item);
|
||||||
|
EAPI void * eina_inlist_append_relative(void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void * eina_inlist_prepend_relative(void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void * eina_inlist_remove(void *in_list, void *in_item);
|
||||||
|
EAPI void * eina_inlist_find(void *in_list, void *in_item);
|
||||||
|
|
||||||
|
//typedef Eina_Bool (*Eina_Iterator_Func)(Eina_Inlist *l, void *data);
|
||||||
|
|
||||||
|
#define EINA_ITER_NEXT(list, l) for (l = (Eina_Inlist *)list; l; l = l->next)
|
||||||
|
#define EINA_ITER_LAST(list, l) for (l = ((Eina_Inlist *)list)->last; l; l = l->prev)
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /*EINA_INLIST_H_*/
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef EINA_LALLOC_H_
|
||||||
|
#define EINA_LALLOC_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Array_Group Array
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void (*Eina_Array_Alloc) (void *user_data, int num);
|
||||||
|
#define EINA_ARRAY_ALLOC(function) ((Eina_Array_Alloc)function)
|
||||||
|
typedef void (*Eina_Array_Free) (void *user_data);
|
||||||
|
#define EINA_ARRAY_FREE(function) ((Eina_Array_Free)function)
|
||||||
|
|
||||||
|
typedef struct _Eina_Array Eina_Array;
|
||||||
|
EAPI void eina_array_free(Eina_Array *a);
|
||||||
|
EAPI Eina_Array *eina_array_new(void *data, Eina_Array_Alloc alloc_cb, Eina_Array_Free free_cb, int num_init);
|
||||||
|
EAPI void eina_array_elements_add(Eina_Array *a, int num);
|
||||||
|
EAPI void eina_array_element_add(Eina_Array *a);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef EINA_LIST_H_
|
||||||
|
#define EINA_LIST_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup List_Group List
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _Eina_List Eina_List;
|
||||||
|
|
||||||
|
EAPI Eina_List *eina_list_append (Eina_List *list, const void *data);
|
||||||
|
EAPI Eina_List *eina_list_prepend (Eina_List *list, const void *data);
|
||||||
|
EAPI Eina_List *eina_list_append_relative (Eina_List *list, const void *data, const void *relative);
|
||||||
|
EAPI Eina_List *eina_list_append_relative_list (Eina_List *list, const void *data, Eina_List *relative);
|
||||||
|
EAPI Eina_List *eina_list_prepend_relative (Eina_List *list, const void *data, const void *relative);
|
||||||
|
EAPI Eina_List *eina_list_prepend_relative_list (Eina_List *list, const void *data, Eina_List *relative);
|
||||||
|
EAPI Eina_List *eina_list_remove (Eina_List *list, const void *data);
|
||||||
|
EAPI Eina_List *eina_list_remove_list (Eina_List *list, Eina_List *remove_list);
|
||||||
|
EAPI Eina_List *eina_list_promote_list (Eina_List *list, Eina_List *move_list);
|
||||||
|
EAPI void *eina_list_find(const Eina_List *list, const void *data);
|
||||||
|
EAPI Eina_List *eina_list_find_list (const Eina_List *list, const void *data);
|
||||||
|
EAPI Eina_List *eina_list_free (Eina_List *list);
|
||||||
|
EAPI Eina_List *eina_list_last (const Eina_List *list);
|
||||||
|
EAPI Eina_List *eina_list_next (const Eina_List *list);
|
||||||
|
EAPI Eina_List *eina_list_prev (const Eina_List *list);
|
||||||
|
EAPI void *eina_list_data(const Eina_List *list);
|
||||||
|
EAPI int eina_list_count(const Eina_List *list);
|
||||||
|
EAPI void *eina_list_nth(const Eina_List *list, int n);
|
||||||
|
EAPI Eina_List *eina_list_nth_list (const Eina_List *list, int n);
|
||||||
|
EAPI Eina_List *eina_list_reverse (Eina_List *list);
|
||||||
|
EAPI Eina_List *eina_list_sort (Eina_List *list, int size, int(*func)(void*,void*));
|
||||||
|
EAPI int eina_list_alloc_error(void);
|
||||||
|
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* EINA_LIST_H_ */
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef EINA_MEMPOOL_H_
|
||||||
|
#define EINA_MEMPOOL_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Memory_Pool_Group Memory Pool
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
typedef struct _Eina_Mempool Eina_Mempool;
|
||||||
|
|
||||||
|
EAPI int eina_mempool_init(void);
|
||||||
|
EAPI int eina_mempool_shutdown(void);
|
||||||
|
EAPI void eina_mempool_delete(Eina_Mempool *mp);
|
||||||
|
EAPI Eina_Mempool * eina_mempool_new_from_buffer(const char *name, void *buffer,
|
||||||
|
unsigned int size, const char *options, ...);
|
||||||
|
EAPI Eina_Mempool * eina_mempool_new(const char *name, unsigned int size, const char
|
||||||
|
*options, ...);
|
||||||
|
EAPI void * eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size);
|
||||||
|
EAPI void * eina_mempool_alloc(Eina_Mempool *mp, unsigned int size);
|
||||||
|
EAPI void eina_mempool_free(Eina_Mempool *mp, void *element);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* EINA_MEMPOOL_H_ */
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef EINA_MODULE_H_
|
||||||
|
#define EINA_MODULE_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Module_Group Module
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _Eina_Module Eina_Module;
|
||||||
|
|
||||||
|
typedef int (*Eina_Module_Cb)(Eina_Module *m, void *data);
|
||||||
|
|
||||||
|
EAPI Eina_Module * eina_module_new(const char *file);
|
||||||
|
EAPI void eina_module_free(Eina_Module *m);
|
||||||
|
EAPI void eina_module_unload(Eina_Module *m);
|
||||||
|
EAPI char * eina_module_path_get(Eina_Module *m);
|
||||||
|
EAPI char * eina_module_name_get(Eina_Module *m);
|
||||||
|
EAPI void * eina_module_symbol_get(Eina_Module *m, const char *symbol);
|
||||||
|
|
||||||
|
EAPI Eina_List * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data);
|
||||||
|
EAPI void eina_module_list_load(Eina_List *list);
|
||||||
|
EAPI void eina_module_list_unload(Eina_List *list);
|
||||||
|
EAPI void eina_module_list_free(Eina_List *list);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /*EINA_MODULE_H_*/
|
|
@ -0,0 +1,148 @@
|
||||||
|
#ifndef EINA_PRIVATE_H_
|
||||||
|
#define EINA_PRIVATE_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
# define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
# define MIN(x, y) (((x) > (y)) ? (y) : (x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX
|
||||||
|
# define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ABS
|
||||||
|
# define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CLAMP
|
||||||
|
# define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define READBUFSIZ 65536
|
||||||
|
|
||||||
|
#define EINA_MAGIC_NONE 0x1234fedc
|
||||||
|
#define EINA_MAGIC_EXE 0xf7e812f5
|
||||||
|
#define EINA_MAGIC_TIMER 0xf7d713f4
|
||||||
|
#define EINA_MAGIC_IDLER 0xf7c614f3
|
||||||
|
#define EINA_MAGIC_IDLE_ENTERER 0xf7b515f2
|
||||||
|
#define EINA_MAGIC_IDLE_EXITER 0xf7601afd
|
||||||
|
#define EINA_MAGIC_FD_HANDLER 0xf7a416f1
|
||||||
|
#define EINA_MAGIC_EVENT_HANDLER 0xf79317f0
|
||||||
|
#define EINA_MAGIC_EVENT_FILTER 0xf78218ff
|
||||||
|
#define EINA_MAGIC_EVENT 0xf77119fe
|
||||||
|
#define EINA_MAGIC_ANIMATOR 0xf7643ea5
|
||||||
|
|
||||||
|
#define EINA_MAGIC Eina_Magic __magic
|
||||||
|
|
||||||
|
#define EINA_MAGIC_SET(d, m) (d)->__magic = (m)
|
||||||
|
#define EINA_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
|
||||||
|
#define EINA_MAGIC_FAIL(d, m, fn) _eina_magic_fail((d), (d) ? (d)->__magic : 0, (m), (fn));
|
||||||
|
|
||||||
|
/* undef the following, we want out version */
|
||||||
|
#undef FREE
|
||||||
|
#define FREE(ptr) free(ptr); ptr = NULL;
|
||||||
|
|
||||||
|
#undef IF_FREE
|
||||||
|
#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
|
||||||
|
|
||||||
|
#undef IF_FN_DEL
|
||||||
|
#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
|
||||||
|
|
||||||
|
inline void eina_print_warning(const char *function, const char *sparam);
|
||||||
|
|
||||||
|
/* convenience macros for checking pointer parameters for non-NULL */
|
||||||
|
#undef CHECK_PARAM_POINTER_RETURN
|
||||||
|
#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
|
||||||
|
if (!(param)) \
|
||||||
|
{ \
|
||||||
|
eina_print_warning(__FUNCTION__, sparam); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef CHECK_PARAM_POINTER
|
||||||
|
#define CHECK_PARAM_POINTER(sparam, param) \
|
||||||
|
if (!(param)) \
|
||||||
|
{ \
|
||||||
|
eina_print_warning(__FUNCTION__, sparam); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef unsigned int Eina_Magic;
|
||||||
|
|
||||||
|
typedef struct _Eina_List2 Eina_List2;
|
||||||
|
typedef struct _Eina_List2_Data Eina_List2_Data;
|
||||||
|
|
||||||
|
struct _Eina_List2
|
||||||
|
{
|
||||||
|
Eina_List2 *next, *prev;
|
||||||
|
Eina_List2 *last;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Eina_List2_Data
|
||||||
|
{
|
||||||
|
Eina_List2 __list_data;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef EINA_H
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EAPI void _eina_magic_fail(void *d, Eina_Magic m, Eina_Magic req_m, const char *fname);
|
||||||
|
|
||||||
|
EAPI void *_eina_list2_append (void *in_list, void *in_item);
|
||||||
|
EAPI void *_eina_list2_prepend (void *in_list, void *in_item);
|
||||||
|
EAPI void *_eina_list2_append_relative (void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void *_eina_list2_prepend_relative (void *in_list, void *in_item, void *in_relative);
|
||||||
|
EAPI void *_eina_list2_remove (void *in_list, void *in_item);
|
||||||
|
EAPI void *_eina_list2_find (void *in_list, void *in_item);
|
||||||
|
|
||||||
|
void _eina_fps_debug_init(void);
|
||||||
|
void _eina_fps_debug_shutdown(void);
|
||||||
|
void _eina_fps_debug_runtime_add(double t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern int _eina_fps_debug;
|
||||||
|
|
||||||
|
|
||||||
|
/* old code finish */
|
||||||
|
/* mp */
|
||||||
|
typedef struct _Eina_Mempool_Backend
|
||||||
|
{
|
||||||
|
void *(*init)(void *buffer, unsigned int size, const char *options, va_list args);
|
||||||
|
void (*free)(void *data, void *element);
|
||||||
|
void *(*alloc)(void *data, unsigned int size);
|
||||||
|
void *(*realloc)(void *data, void *element, unsigned int size);
|
||||||
|
void (*garbage_collect)(void);
|
||||||
|
void (*statistics)(void);
|
||||||
|
void (*shutdown)(void *data);
|
||||||
|
} Eina_Mempool_Backend;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* EINA_PRIVATE_H_ */
|
|
@ -0,0 +1,196 @@
|
||||||
|
#ifndef EINA_RECTANGLE_H_
|
||||||
|
#define EINA_RECTANGLE_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
typedef struct _Eina_Rectangle
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
} Eina_Rectangle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
* Is it needed??
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
eina_spans_intersect(int c1, int l1, int c2, int l2)
|
||||||
|
{
|
||||||
|
return (!(((c2 + l2) <= c1) || (c2 >= (c1 + l1))));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_is_empty(Eina_Rectangle *r)
|
||||||
|
{
|
||||||
|
return ((r->w < 1) || (r->h < 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
eina_rectangle_coords_from(Eina_Rectangle *r, int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
r->x = x;
|
||||||
|
r->y = y;
|
||||||
|
r->w = w;
|
||||||
|
r->h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangles_intersect(Eina_Rectangle *r1, Eina_Rectangle *r2)
|
||||||
|
{
|
||||||
|
return (eina_spans_intersect(r1->x, r1->w, r2->x, r2->w) && eina_spans_intersect(r1->y, r1->h, r2->y, r2->h));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_hspan_inside(Eina_Rectangle *r, int x, int l)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_vspan_inside(Eina_Rectangle *r, int y, int l)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_xcoord_inside(Eina_Rectangle *r, int x)
|
||||||
|
{
|
||||||
|
return ((x >= r->x) && (x < (r->x + r->w)));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_ycoord_inside(Eina_Rectangle *r, int y)
|
||||||
|
{
|
||||||
|
return ((y >= r->y) && (y < (r->y + r->h)));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_coords_inside(Eina_Rectangle *r, int x, int y)
|
||||||
|
{
|
||||||
|
return (eina_rectangle_xcoord_inside(r, x) && eina_rectangle_ycoord_inside(r, y));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
eina_rectangle_union(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||||
|
{
|
||||||
|
/* left */
|
||||||
|
if (dst->x > src->x)
|
||||||
|
{
|
||||||
|
dst->w += dst->x - src->x;
|
||||||
|
dst->x = src->x;
|
||||||
|
}
|
||||||
|
/* right */
|
||||||
|
if ((dst->x + dst->w) < (src->x + src->w))
|
||||||
|
dst->w = src->x + src->w;
|
||||||
|
/* top */
|
||||||
|
if (dst->y > src->y)
|
||||||
|
{
|
||||||
|
dst->h += dst->y - src->y;
|
||||||
|
dst->y = src->y;
|
||||||
|
}
|
||||||
|
/* bottom */
|
||||||
|
if ((dst->y + dst->h) < (src->y + src->h))
|
||||||
|
dst->h = src->y + src->h;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline Eina_Bool
|
||||||
|
eina_rectangle_intersection(Eina_Rectangle *dst, Eina_Rectangle *src)
|
||||||
|
{
|
||||||
|
if (!(eina_rectangles_intersect(dst, src)))
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
/* left */
|
||||||
|
if (dst->x < src->x)
|
||||||
|
{
|
||||||
|
dst->w += dst->x - src->x;
|
||||||
|
dst->x = src->x;
|
||||||
|
if (dst->w < 0)
|
||||||
|
dst->w = 0;
|
||||||
|
}
|
||||||
|
/* right */
|
||||||
|
if ((dst->x + dst->w) > (src->x + src->w))
|
||||||
|
dst->w = src->x + src->w - dst->x;
|
||||||
|
/* top */
|
||||||
|
if (dst->y < src->y)
|
||||||
|
{
|
||||||
|
dst->h += dst->y - src->y;
|
||||||
|
dst->y = src->y;
|
||||||
|
if (dst->h < 0)
|
||||||
|
dst->h = 0;
|
||||||
|
}
|
||||||
|
/* bottom */
|
||||||
|
if ((dst->y + dst->h) > (src->y + src->h))
|
||||||
|
dst->h = src->y + src->h - dst->y;
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rescale the coordinates from @in as if it where relative to @out
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
eina_rectangle_rescale_in(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||||
|
{
|
||||||
|
res->x = in->x - out->x;
|
||||||
|
res->y = in->y - out->y;
|
||||||
|
res->w = in->w;
|
||||||
|
res->h = in->h;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
eina_rectangle_rescale_out(Eina_Rectangle *out, Eina_Rectangle *in, Eina_Rectangle *res)
|
||||||
|
{
|
||||||
|
res->x = out->x + in->x;
|
||||||
|
res->y = out->y + in->y;
|
||||||
|
res->w = out->w;
|
||||||
|
res->h = out->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /*_ENESIM_RECTANGLE_H_*/
|
|
@ -0,0 +1,62 @@
|
||||||
|
#ifndef EINA_TYPES_H_
|
||||||
|
#define EINA_TYPES_H_
|
||||||
|
|
||||||
|
#ifdef EAPI
|
||||||
|
# undef EAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# ifdef EFL_EINA_BUILD
|
||||||
|
# ifdef DLL_EXPORT
|
||||||
|
# define EAPI __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif /* ! DLL_EXPORT */
|
||||||
|
# else
|
||||||
|
# define EAPI __declspec(dllimport)
|
||||||
|
# endif /* ! EFL_EINA_BUILD */
|
||||||
|
#else
|
||||||
|
# ifdef __GNUC__
|
||||||
|
# if __GNUC__ >= 4
|
||||||
|
# define EAPI __attribute__ ((visibility("default")))
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define EAPI
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* remove this TRUE/FALSE redifinitions */
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
# define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
# define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EINA_FALSE = 0,
|
||||||
|
EINA_TRUE = 1
|
||||||
|
} Eina_Bool;
|
||||||
|
|
||||||
|
EAPI extern const unsigned int eina_prime_table[];
|
||||||
|
|
||||||
|
#define EINA_SORT_MIN 0
|
||||||
|
#define EINA_SORT_MAX 1
|
||||||
|
|
||||||
|
typedef void (*Eina_For_Each) (void *value, void *user_data);
|
||||||
|
#define EINA_FOR_EACH(function) ((Eina_For_Each)function)
|
||||||
|
|
||||||
|
typedef void (*Eina_Free_Cb) (void *data);
|
||||||
|
#define EINA_FREE_CB(func) ((Eina_Free_Cb)func)
|
||||||
|
|
||||||
|
typedef unsigned int (*Eina_Hash_Cb) (const void *key);
|
||||||
|
#define EINA_HASH_CB(function) ((Eina_Hash_Cb)function)
|
||||||
|
|
||||||
|
typedef int (*Eina_Compare_Cb) (const void *data1, const void *data2);
|
||||||
|
#define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function)
|
||||||
|
|
||||||
|
#endif /*EINA_TYPES_H_*/
|
|
@ -0,0 +1,21 @@
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I$(top_srcdir)/src/include
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libeina.la
|
||||||
|
|
||||||
|
libeina_la_SOURCES = \
|
||||||
|
eina_error.c \
|
||||||
|
eina_hash.c \
|
||||||
|
eina_lalloc.c \
|
||||||
|
eina_inlist.c \
|
||||||
|
eina_file.c \
|
||||||
|
eina_mempool.c \
|
||||||
|
eina_list.c \
|
||||||
|
eina_module.c \
|
||||||
|
eina_value.c
|
||||||
|
|
||||||
|
libeina_la_LIBADD = -ldl
|
||||||
|
libeina_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
|
||||||
|
libeina_la_DEPENDENCIES = $(top_builddir)/config.h
|
|
@ -0,0 +1,153 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
/* TODO
|
||||||
|
* + printing errors to stdout or stderr can be implemented
|
||||||
|
* using a queue, usful for multiple threads printing
|
||||||
|
* + add a wapper for assert?
|
||||||
|
* + add common error numbers, messages
|
||||||
|
* + add a calltrace of erros, not only store the last error but a list of them
|
||||||
|
* and also store the function that set it
|
||||||
|
*/
|
||||||
|
/*============================================================================*
|
||||||
|
* Local *
|
||||||
|
*============================================================================*/
|
||||||
|
static int _curr = 1;
|
||||||
|
static int _init_count = 0;
|
||||||
|
static Eina_List *_error_list;
|
||||||
|
static int _err;
|
||||||
|
|
||||||
|
#define RED "\033[31;1m"
|
||||||
|
#define GREEN "\033[32;1m"
|
||||||
|
#define YELLOW "\033[33;1m"
|
||||||
|
#define WHITE "\033[37;1m"
|
||||||
|
#define NOTHING "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static _error_level = EINA_ERROR_LEVEL_DBG;
|
||||||
|
#else
|
||||||
|
static _error_level = EINA_ERROR_LEVEL_ERR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *_colors[EINA_ERROR_LEVELS] = {
|
||||||
|
[EINA_ERROR_LEVEL_ERR] = RED,
|
||||||
|
[EINA_ERROR_LEVEL_WARN] = YELLOW,
|
||||||
|
[EINA_ERROR_LEVEL_INFO] = NOTHING,
|
||||||
|
[EINA_ERROR_LEVEL_DBG] = GREEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _error_print(Eina_Error_Level level, const char *file,
|
||||||
|
const char *fnc, int line, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
if (level <= _error_level)
|
||||||
|
{
|
||||||
|
printf("%s", _colors[level]);
|
||||||
|
printf("[%s:%d] %s() ", file, line, fnc);
|
||||||
|
printf("%s", _colors[EINA_ERROR_LEVEL_INFO]);
|
||||||
|
vprintf(fmt, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* Global *
|
||||||
|
*============================================================================*/
|
||||||
|
void eina_error_magic_check(unsigned int magic, unsigned int cmp)
|
||||||
|
{
|
||||||
|
assert(magic == cmp);
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_error_init(void)
|
||||||
|
{
|
||||||
|
if (!_init_count)
|
||||||
|
{
|
||||||
|
char *level;
|
||||||
|
/* TODO register the eina's basic errors */
|
||||||
|
/* TODO load the environment variable for getting the log level */
|
||||||
|
if (level = getenv("EINA_ERROR_LEVEL"))
|
||||||
|
{
|
||||||
|
_error_level = atoi(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* get all the modules */
|
||||||
|
return ++_init_count;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_error_shutdown(void)
|
||||||
|
{
|
||||||
|
if (!_init_count)
|
||||||
|
return _init_count;
|
||||||
|
_init_count--;
|
||||||
|
if (!_init_count)
|
||||||
|
{
|
||||||
|
/* remove the error strings */
|
||||||
|
while (_error_list)
|
||||||
|
{
|
||||||
|
free(eina_list_data(_error_list));
|
||||||
|
_error_list = eina_list_free(_error_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _init_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new error type
|
||||||
|
* @param str The description of the error
|
||||||
|
* @return The unique number identifier for this error
|
||||||
|
*/
|
||||||
|
EAPI int eina_error_register(const char *msg)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
str = strdup(msg);
|
||||||
|
_error_list = eina_list_append(_error_list, str);
|
||||||
|
|
||||||
|
return ++_curr;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_error_get(void)
|
||||||
|
{
|
||||||
|
return _err;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_error_set(int err)
|
||||||
|
{
|
||||||
|
_err = err;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Given an error number return the description of it
|
||||||
|
* @param error The error number
|
||||||
|
* @return The description of the error
|
||||||
|
*/
|
||||||
|
EAPI const char * eina_error_msg_get(int error)
|
||||||
|
{
|
||||||
|
return eina_list_nth(_error_list, error);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_error_print(Eina_Error_Level level, const char *file,
|
||||||
|
const char *fnc, int line, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
_error_print(level, file, fnc, line, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_error_log_level_set(Eina_Error_Level level)
|
||||||
|
{
|
||||||
|
_error_level = level;
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
* Lis all files on the directory calling the function for every file found
|
||||||
|
* @param recursive Iterate recursively in the directory
|
||||||
|
*/
|
||||||
|
EAPI void eina_file_dir_list(const char *dir, int recursive, Eina_File_Dir_List_Cb cb, void *data)
|
||||||
|
{
|
||||||
|
struct dirent *de;
|
||||||
|
DIR *d;
|
||||||
|
|
||||||
|
assert(cb);
|
||||||
|
|
||||||
|
d = opendir(dir);
|
||||||
|
if (!d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (de = readdir(d))
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
|
||||||
|
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cb(de->d_name, dir, data);
|
||||||
|
/* d_type is only available on linux and bsd (_BSD_SOURCE) */
|
||||||
|
if ((recursive) && (de->d_type == DT_DIR))
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "%s/%s", dir, de->d_name);
|
||||||
|
eina_file_dir_list(path, recursive, cb, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_file_path_nth_get(const char *path, int n, char **left, char **right)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char *end;
|
||||||
|
char *tmp;
|
||||||
|
char *delim;
|
||||||
|
int inc;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
if (!left && !right)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
p = (char *)path;
|
||||||
|
inc = 1;
|
||||||
|
end = (char *)path + strlen(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = (char *)path + strlen(path);
|
||||||
|
inc = -1;
|
||||||
|
end = (char *)path;
|
||||||
|
}
|
||||||
|
for (tmp = p; tmp != end, num != n; tmp += inc)
|
||||||
|
{
|
||||||
|
if (*tmp == '/')
|
||||||
|
{
|
||||||
|
num += inc;
|
||||||
|
delim = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (left)
|
||||||
|
{
|
||||||
|
*left = strndup(path, delim - path + 1);
|
||||||
|
}
|
||||||
|
if (right)
|
||||||
|
{
|
||||||
|
*right = strdup(delim + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,473 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
/*============================================================================*
|
||||||
|
* Local *
|
||||||
|
*============================================================================*/
|
||||||
|
typedef struct _Eina_Hash_El Eina_Hash_El;
|
||||||
|
|
||||||
|
struct _Eina_Hash
|
||||||
|
{
|
||||||
|
int population;
|
||||||
|
Eina_Inlist *buckets[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _Eina_Hash_El
|
||||||
|
{
|
||||||
|
Eina_Inlist _list_data;
|
||||||
|
const char *key;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int _eina_hash_gen(const char *key);
|
||||||
|
|
||||||
|
static int _eina_hash_alloc_error = 0;
|
||||||
|
|
||||||
|
static inline int _eina_hash_gen(const char *key)
|
||||||
|
{
|
||||||
|
unsigned int hash_num = 5381;
|
||||||
|
const unsigned char *ptr;
|
||||||
|
|
||||||
|
if (!key)
|
||||||
|
return 0;
|
||||||
|
for (ptr = (unsigned char *)key; *ptr; ptr++)
|
||||||
|
hash_num = (hash_num * 33) ^ *ptr;
|
||||||
|
|
||||||
|
hash_num &= 0xff;
|
||||||
|
return (int)hash_num;
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* Global *
|
||||||
|
*============================================================================*/
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
* Adds an entry to the given hash table.
|
||||||
|
*
|
||||||
|
* @p key is expected to be a unique string within the hash table.
|
||||||
|
* Otherwise, you cannot be sure which inserted data pointer will be
|
||||||
|
* accessed with @ref eina_hash_find , and removed with
|
||||||
|
* @ref eina_hash_del .
|
||||||
|
*
|
||||||
|
* Key strings are case sensitive.
|
||||||
|
*
|
||||||
|
* @ref eina_hash_alloc_error should be used to determine if an
|
||||||
|
* allocation error occurred during this function.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table. Can be @c NULL, in which case a
|
||||||
|
* new hash table is allocated and returned.
|
||||||
|
* @param key A unique string. Can be @c NULL.
|
||||||
|
* @param data Data to associate with the string given by @p key.
|
||||||
|
* @return Either the given hash table, or if the given value for @p
|
||||||
|
* hash is @c NULL, then a new one. @c NULL will be returned
|
||||||
|
* if memory could not be allocated for a new table.
|
||||||
|
*/
|
||||||
|
EAPI Eina_Hash *
|
||||||
|
eina_hash_add(Eina_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
|
||||||
|
if ((!key) || (!data)) return hash;
|
||||||
|
_eina_hash_alloc_error = 0;
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
hash = calloc(1, sizeof(struct _Eina_Hash));
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(el = malloc(sizeof(struct _Eina_Hash_El) + strlen(key) + 1)))
|
||||||
|
{
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
el->key = ((char *)el) + sizeof(struct _Eina_Hash_El);
|
||||||
|
strcpy((char *) el->key, key);
|
||||||
|
el->data = (void *)data;
|
||||||
|
hash_num = _eina_hash_gen(key);
|
||||||
|
hash->buckets[hash_num] = eina_inlist_prepend(hash->buckets[hash_num], el);
|
||||||
|
if (eina_list_alloc_error())
|
||||||
|
{
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
free(el);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
hash->population++;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Adds an entry to the given hash table and does not duplicate the string key.
|
||||||
|
*
|
||||||
|
* @p key is expected to be a unique string within the hash table.
|
||||||
|
* Otherwise, you cannot be sure which inserted data pointer will be
|
||||||
|
* accessed with @ref eina_hash_find , and removed with
|
||||||
|
* @ref eina_hash_del . This call does not make a copy of the key so it must
|
||||||
|
* be a string constant or stored elsewhere (in the object being added) etc.
|
||||||
|
*
|
||||||
|
* Key strings are case sensitive.
|
||||||
|
*
|
||||||
|
* @ref eina_hash_alloc_error should be used to determine if an
|
||||||
|
* allocation error occurred during this function.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table. Can be @c NULL, in which case a
|
||||||
|
* new hash table is allocated and returned.
|
||||||
|
* @param key A unique string. Can be @c NULL.
|
||||||
|
* @param data Data to associate with the string given by @p key.
|
||||||
|
* @return Either the given hash table, or if the given value for @p
|
||||||
|
* hash is @c NULL, then a new one. @c NULL will be returned
|
||||||
|
* if memory could not be allocated for a new table.
|
||||||
|
* @ingroup Eina_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI Eina_Hash *
|
||||||
|
eina_hash_direct_add(Eina_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
|
||||||
|
if ((!key) || (!data)) return hash;
|
||||||
|
_eina_hash_alloc_error = 0;
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
hash = calloc(1, sizeof(struct _Eina_Hash));
|
||||||
|
if (!hash)
|
||||||
|
{
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(el = malloc(sizeof(struct _Eina_Hash_El))))
|
||||||
|
{
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
el->key = key;
|
||||||
|
el->data = (void *)data;
|
||||||
|
hash_num = _eina_hash_gen(key);
|
||||||
|
hash->buckets[hash_num] = eina_inlist_prepend(hash->buckets[hash_num], el);
|
||||||
|
if (eina_list_alloc_error())
|
||||||
|
{
|
||||||
|
_eina_hash_alloc_error = 1;
|
||||||
|
free(el);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
hash->population++;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the entry identified by @p key or @p data from the given
|
||||||
|
* hash table.
|
||||||
|
*
|
||||||
|
* If @p key is @c NULL, then @p data is used to find a match to
|
||||||
|
* remove.
|
||||||
|
*
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string. Can be @c NULL.
|
||||||
|
* @param data The data pointer to remove if @p key is @c NULL.
|
||||||
|
* Otherwise, not required and can be @c NULL.
|
||||||
|
* @return The modified hash table. If there are no entries left, the
|
||||||
|
* hash table will be freed and @c NULL will be returned.
|
||||||
|
* @ingroup Eina_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI Eina_Hash *
|
||||||
|
eina_hash_del(Eina_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
Eina_Inlist *l;
|
||||||
|
|
||||||
|
if (!hash) return NULL;
|
||||||
|
if (!key)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
|
||||||
|
for (hash_num = 0; hash_num < 256; hash_num++)
|
||||||
|
{
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Eina_Hash_El *)l;
|
||||||
|
if (el->data == data)
|
||||||
|
{
|
||||||
|
hash->buckets[hash_num] = eina_inlist_remove(hash->buckets[hash_num], el);
|
||||||
|
free(el);
|
||||||
|
hash->population--;
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash_num = _eina_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next)
|
||||||
|
{
|
||||||
|
el = (Eina_Hash_El *)l;
|
||||||
|
if (!strcmp(el->key, key))
|
||||||
|
{
|
||||||
|
hash->buckets[hash_num] = eina_inlist_remove(hash->buckets[hash_num], el);
|
||||||
|
free(el);
|
||||||
|
hash->population--;
|
||||||
|
if (hash->population <= 0)
|
||||||
|
{
|
||||||
|
free(hash);
|
||||||
|
hash = NULL;
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a specific entry in the given hash table.
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string of the entry to find.
|
||||||
|
* @return The data pointer for the stored entry, or @c NULL if not
|
||||||
|
* found.
|
||||||
|
* @ingroup Eina_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI void * eina_hash_find(const Eina_Hash *hash, const char *key)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
Eina_Inlist *l;
|
||||||
|
|
||||||
|
_eina_hash_alloc_error = 0;
|
||||||
|
if ((!hash) || (!key))
|
||||||
|
return NULL;
|
||||||
|
hash_num = _eina_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next) {
|
||||||
|
el = (Eina_Hash_El *)l;
|
||||||
|
if (!strcmp(el->key, key)) {
|
||||||
|
if (l != hash->buckets[hash_num]) {
|
||||||
|
Eina_Inlist *bucket;
|
||||||
|
|
||||||
|
bucket = hash->buckets[hash_num];
|
||||||
|
bucket = eina_inlist_remove(bucket, el);
|
||||||
|
bucket = eina_inlist_prepend(bucket, el);
|
||||||
|
((Eina_Hash *)hash)->buckets[hash_num]
|
||||||
|
= bucket;
|
||||||
|
}
|
||||||
|
return el->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the entry pointer at the specified key and returns the old entry
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @param key The key string of the entry to modify.
|
||||||
|
* @param data The data to replace the old entry, if it exists.
|
||||||
|
* @return The data pointer for the old stored entry, or @c NULL if not
|
||||||
|
* found. If an existing entry is not found, nothing is added to the
|
||||||
|
* hash.
|
||||||
|
* @ingroup Eina_Hash_Data
|
||||||
|
*/
|
||||||
|
EAPI void * eina_hash_modify(Eina_Hash *hash, const char *key, const void *data)
|
||||||
|
{
|
||||||
|
int hash_num;
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
Eina_Inlist *l;
|
||||||
|
|
||||||
|
_eina_hash_alloc_error = 0;
|
||||||
|
if (!hash)
|
||||||
|
return NULL;
|
||||||
|
hash_num = _eina_hash_gen(key);
|
||||||
|
for (l = hash->buckets[hash_num]; l; l = l->next) {
|
||||||
|
el = (Eina_Hash_El *)l;
|
||||||
|
if ((key) && (!strcmp(el->key, key))) {
|
||||||
|
void *old_data;
|
||||||
|
|
||||||
|
if (l != hash->buckets[hash_num]) {
|
||||||
|
hash->buckets[hash_num]
|
||||||
|
= eina_inlist_remove(
|
||||||
|
hash->buckets[hash_num],
|
||||||
|
el);
|
||||||
|
hash->buckets[hash_num]
|
||||||
|
= eina_inlist_prepend(
|
||||||
|
hash->buckets[hash_num],
|
||||||
|
el);
|
||||||
|
}
|
||||||
|
old_data = el->data;
|
||||||
|
el->data = (void *) data;
|
||||||
|
return old_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Eina_Hash_General_Group Hash General Functions
|
||||||
|
*
|
||||||
|
* Miscellaneous functions that operate on hash objects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the number of buckets available in the given hash table.
|
||||||
|
* @param hash The given hash table.
|
||||||
|
* @return @c 256 if @p hash is not @c NULL. @c 0 otherwise.
|
||||||
|
* @ingroup Eina_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI int eina_hash_size(const Eina_Hash *hash)
|
||||||
|
{
|
||||||
|
if (!hash)
|
||||||
|
return 0;
|
||||||
|
return 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Complete polishing documentation for eina_hash.c. The
|
||||||
|
* functions' docs may be grouped, but they need some simplification.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an entire hash table
|
||||||
|
* @param hash The hash table to be freed
|
||||||
|
*
|
||||||
|
* This function frees up all the memory allocated to storing the specified
|
||||||
|
* hash tale pointed to by @p hash. Any entries in the table that the program
|
||||||
|
* has no more pointers for elsewhere may now be lost, so this should only be
|
||||||
|
* called if the program has lready freed any allocated data in the hash table
|
||||||
|
* or has the pointers for data in teh table stored elswehere as well.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* extern Eina_Hash *hash;
|
||||||
|
*
|
||||||
|
* eina_hash_free(hash);
|
||||||
|
* hash = NULL;
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Eina_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI void eina_hash_free(Eina_Hash *hash)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
if (!hash)
|
||||||
|
return;
|
||||||
|
size = eina_hash_size(hash);
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
while (hash->buckets[i]) {
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
|
||||||
|
el = (Eina_Hash_El *)hash->buckets[i];
|
||||||
|
hash->buckets[i] = eina_inlist_remove(
|
||||||
|
hash->buckets[i], el);
|
||||||
|
free(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call a function on every member stored in the hash table
|
||||||
|
* @param hash The hash table whose members will be walked
|
||||||
|
* @param func The function to call on each parameter
|
||||||
|
* @param fdata The data pointer to pass to the function being called
|
||||||
|
*
|
||||||
|
* This function goes through every entry in the hash table @p hash and calls
|
||||||
|
* the function @p func on each member. The function should NOT modify the
|
||||||
|
* hash table contents if it returns 1. IF the hash table contents are
|
||||||
|
* modified by this function or the function wishes to stop processing it must
|
||||||
|
* return 0, otherwise return 1 to keep processing.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* extern Eina_Hash *hash;
|
||||||
|
*
|
||||||
|
* Eina_Bool hash_fn(Eina_Hash *hash, const char *key, void *data, void *fdata)
|
||||||
|
* {
|
||||||
|
* printf("Func data: %s, Hash entry: %s / %p\n", fdata, key, data);
|
||||||
|
* return 1;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* int main(int argc, char **argv)
|
||||||
|
* {
|
||||||
|
* char *hash_fn_data;
|
||||||
|
*
|
||||||
|
* hash_fn_data = strdup("Hello World");
|
||||||
|
* eina_hash_foreach(hash, hash_fn, hash_fn_data);
|
||||||
|
* free(hash_fn_data);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Eina_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI void eina_hash_foreach(
|
||||||
|
const Eina_Hash *hash,
|
||||||
|
Eina_Bool (*func) (const Eina_Hash *hash, const char *key, void *data, void *fdata),
|
||||||
|
const void *fdata)
|
||||||
|
{
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
if (!hash)
|
||||||
|
return;
|
||||||
|
size = eina_hash_size(hash);
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
Eina_Inlist *l, *next_l;
|
||||||
|
|
||||||
|
for (l = hash->buckets[i]; l;) {
|
||||||
|
Eina_Hash_El *el;
|
||||||
|
|
||||||
|
next_l = l->next;
|
||||||
|
el = (Eina_Hash_El *)l;
|
||||||
|
if (!func(hash, el->key, el->data, (void *)fdata))
|
||||||
|
return;
|
||||||
|
l = next_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return memory allocation failure flag after an function requiring allocation
|
||||||
|
* @return The state of the allocation flag
|
||||||
|
*
|
||||||
|
* This function returns the state of the memory allocation flag. This flag is
|
||||||
|
* set if memory allocations fail during eina_hash_add() calls. If they do, 1
|
||||||
|
* will be returned, otherwise 0 will be returned. The flag will remain in its
|
||||||
|
* current state until the next call that requires allocation is called, and
|
||||||
|
* is then reset.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* @code
|
||||||
|
* Eina_Hash *hash = NULL;
|
||||||
|
* extern void *my_data;
|
||||||
|
*
|
||||||
|
* hash = eina_hash_add(hash, "My Data", my_data);
|
||||||
|
* if (eina_hash_alloc_error())
|
||||||
|
* {
|
||||||
|
* fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
|
||||||
|
* exit(-1);
|
||||||
|
* }
|
||||||
|
* if (eina_hash_find(hash, "My Data") == my_data)
|
||||||
|
* {
|
||||||
|
* printf("My Data inserted and successfully found.\n");
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @ingroup Eina_Hash_General_Group
|
||||||
|
*/
|
||||||
|
EAPI int eina_hash_alloc_error(void)
|
||||||
|
{
|
||||||
|
return _eina_hash_alloc_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common hash functions */
|
|
@ -0,0 +1,161 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
/* TODO please, refactor this :) */
|
||||||
|
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_append(void *in_list, void *in_item) {
|
||||||
|
Eina_Inlist *l, *new_l;
|
||||||
|
Eina_Inlist *list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
new_l->next = NULL;
|
||||||
|
if (!list) {
|
||||||
|
new_l->prev = NULL;
|
||||||
|
new_l->last = new_l;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
if (list->last)
|
||||||
|
l = list->last;
|
||||||
|
else
|
||||||
|
for (l = list; (l) && (l->next); l = l->next)
|
||||||
|
;
|
||||||
|
l->next = new_l;
|
||||||
|
new_l->prev = l;
|
||||||
|
list->last = new_l;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_prepend(void *in_list, void *in_item) {
|
||||||
|
Eina_Inlist *new_l;
|
||||||
|
Eina_Inlist *list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
new_l->prev = NULL;
|
||||||
|
if (!list) {
|
||||||
|
new_l->next = NULL;
|
||||||
|
new_l->last = new_l;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
new_l->next = list;
|
||||||
|
list->prev = new_l;
|
||||||
|
new_l->last = list->last;
|
||||||
|
list->last = NULL;
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_append_relative(void *in_list, void *in_item,
|
||||||
|
void *in_relative) {
|
||||||
|
Eina_Inlist *list, *relative, *new_l;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
relative = in_relative;
|
||||||
|
if (relative) {
|
||||||
|
if (relative->next) {
|
||||||
|
new_l->next = relative->next;
|
||||||
|
relative->next->prev = new_l;
|
||||||
|
} else
|
||||||
|
new_l->next = NULL;
|
||||||
|
relative->next = new_l;
|
||||||
|
new_l->prev = relative;
|
||||||
|
if (!new_l->next)
|
||||||
|
list->last = new_l;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
return eina_inlist_append(list, new_l);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_prepend_relative(void *in_list, void *in_item,
|
||||||
|
void *in_relative) {
|
||||||
|
Eina_Inlist *list, *relative, *new_l;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
new_l = in_item;
|
||||||
|
relative = in_relative;
|
||||||
|
if (relative) {
|
||||||
|
new_l->prev = relative->prev;
|
||||||
|
new_l->next = relative;
|
||||||
|
relative->prev = new_l;
|
||||||
|
if (new_l->prev) {
|
||||||
|
new_l->prev->next = new_l;
|
||||||
|
if (!new_l->next)
|
||||||
|
list->last = new_l;
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
if (!new_l->next)
|
||||||
|
new_l->last = new_l;
|
||||||
|
else {
|
||||||
|
new_l->last = list->last;
|
||||||
|
list->last = NULL;
|
||||||
|
}
|
||||||
|
return new_l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return eina_inlist_prepend(list, new_l);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_remove(void *in_list, void *in_item) {
|
||||||
|
Eina_Inlist *return_l;
|
||||||
|
Eina_Inlist *list, *item;
|
||||||
|
|
||||||
|
/* checkme */
|
||||||
|
if (!in_list)
|
||||||
|
return in_list;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
item = in_item;
|
||||||
|
if (!item)
|
||||||
|
return list;
|
||||||
|
if (item->next)
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
if (item->prev) {
|
||||||
|
item->prev->next = item->next;
|
||||||
|
return_l = list;
|
||||||
|
} else {
|
||||||
|
return_l = item->next;
|
||||||
|
if (return_l)
|
||||||
|
return_l->last = list->last;
|
||||||
|
}
|
||||||
|
if (item == list->last)
|
||||||
|
list->last = item->prev;
|
||||||
|
item->next = NULL;
|
||||||
|
item->prev = NULL;
|
||||||
|
return return_l;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_inlist_find(void *in_list, void *in_item) {
|
||||||
|
Eina_Inlist *l;
|
||||||
|
Eina_Inlist *list, *item;
|
||||||
|
|
||||||
|
list = in_list;
|
||||||
|
item = in_item;
|
||||||
|
for (l = list; l; l = l->next) {
|
||||||
|
if (l == item)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
struct _Eina_Array
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
int num_allocated;
|
||||||
|
int num_elements;
|
||||||
|
int acc;
|
||||||
|
Eina_Array_Alloc alloc_cb;
|
||||||
|
Eina_Array_Free free_cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI Eina_Array * eina_array_new(void *data, Eina_Array_Alloc alloc_cb, Eina_Array_Free free_cb, int num_init)
|
||||||
|
{
|
||||||
|
Eina_Array *a;
|
||||||
|
|
||||||
|
a = calloc(1, sizeof(Eina_Array));
|
||||||
|
a->data = data;
|
||||||
|
a->alloc_cb = alloc_cb;
|
||||||
|
a->free_cb = free_cb;
|
||||||
|
if (num_init > 0)
|
||||||
|
{
|
||||||
|
a->num_allocated = num_init;
|
||||||
|
a->alloc_cb(a->data, a->num_allocated);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_array_element_add(Eina_Array *a)
|
||||||
|
{
|
||||||
|
if (a->num_elements == a->num_allocated)
|
||||||
|
{
|
||||||
|
a->num_allocated = (1 << a->acc);
|
||||||
|
a->acc++;
|
||||||
|
a->alloc_cb(a->data, a->num_allocated);
|
||||||
|
}
|
||||||
|
a->num_elements++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_array_elements_add(Eina_Array *a, int num)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
tmp = a->num_elements + num;
|
||||||
|
if (tmp > a->num_allocated)
|
||||||
|
{
|
||||||
|
while (tmp > a->num_allocated)
|
||||||
|
{
|
||||||
|
a->num_allocated = (1 << a->acc);
|
||||||
|
a->acc++;
|
||||||
|
}
|
||||||
|
a->alloc_cb(a->data, a->num_allocated);
|
||||||
|
}
|
||||||
|
a->num_elements += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_array_free(Eina_Array *a)
|
||||||
|
{
|
||||||
|
a->free_cb(a->data);
|
||||||
|
free(a);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,151 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
/*============================================================================*
|
||||||
|
* Local *
|
||||||
|
*============================================================================*/
|
||||||
|
static Eina_List *_modules;
|
||||||
|
static int _init_count = 0;
|
||||||
|
|
||||||
|
struct _Eina_Mempool
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
unsigned int magic;
|
||||||
|
#endif
|
||||||
|
Eina_Module *module;
|
||||||
|
Eina_Mempool_Backend *backend;
|
||||||
|
void *backend_data;
|
||||||
|
};
|
||||||
|
static Eina_Mempool * _new_from_buffer(const char *name, void *buffer,
|
||||||
|
unsigned int size, const char *options, va_list args)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
/* load the module with filename == name */
|
||||||
|
for (l = _modules; l; l = eina_list_next(l))
|
||||||
|
{
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
m = eina_list_data(l);
|
||||||
|
/* check if the requested module name exists */
|
||||||
|
if (!strncmp(eina_module_name_get(m), name, strlen(name)))
|
||||||
|
{
|
||||||
|
Eina_Mempool *mp;
|
||||||
|
|
||||||
|
mp = malloc(sizeof(Eina_Mempool));
|
||||||
|
eina_module_load(m);
|
||||||
|
mp->module = m;
|
||||||
|
mp->backend = eina_module_symbol_get(m, "mp_backend");
|
||||||
|
mp->backend_data = mp->backend->init(buffer, size, options, args);
|
||||||
|
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_mempool_init(void)
|
||||||
|
{
|
||||||
|
if (!_init_count)
|
||||||
|
{
|
||||||
|
_modules = eina_module_list_get("/usr/local/lib/eina/mm_policies", 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
/* get all the modules */
|
||||||
|
return ++_init_count;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI int eina_mempool_shutdown(void)
|
||||||
|
{
|
||||||
|
if (!_init_count)
|
||||||
|
return _init_count;
|
||||||
|
_init_count--;
|
||||||
|
if (!_init_count)
|
||||||
|
{
|
||||||
|
/* remove the list of modules */
|
||||||
|
eina_module_list_free(_modules);
|
||||||
|
}
|
||||||
|
return _init_count;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI Eina_Mempool * eina_mempool_new_from_buffer(const char *name, void *buffer,
|
||||||
|
unsigned int size, const char *options, ...)
|
||||||
|
{
|
||||||
|
Eina_Mempool *mp;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(buffer);
|
||||||
|
|
||||||
|
va_start(args, options);
|
||||||
|
mp = _new_from_buffer(name, buffer, size, options, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI Eina_Mempool * eina_mempool_new(const char *name, unsigned int size, const char
|
||||||
|
*options, ...)
|
||||||
|
{
|
||||||
|
Eina_Mempool *mp;
|
||||||
|
void *buffer;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
buffer = malloc(sizeof(char) * size);
|
||||||
|
va_start(args, options);
|
||||||
|
mp = _new_from_buffer(name, buffer, size, options, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_mempool_delete(Eina_Mempool *mp)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
assert(mp);
|
||||||
|
|
||||||
|
mp->backend->shutdown(mp->backend_data);
|
||||||
|
eina_module_unload(mp->module);
|
||||||
|
free(mp);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void * eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void * eina_mempool_alloc(Eina_Mempool *mp, unsigned int size)
|
||||||
|
{
|
||||||
|
assert(mp);
|
||||||
|
assert(mp->backend->alloc);
|
||||||
|
|
||||||
|
return mp->backend->alloc(mp->backend_data, size);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_mempool_free(Eina_Mempool *mp, void *element)
|
||||||
|
{
|
||||||
|
assert(mp);
|
||||||
|
assert(mp->backend->free);
|
||||||
|
|
||||||
|
mp->backend->free(mp->backend_data, element);
|
||||||
|
}
|
|
@ -0,0 +1,280 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
/*============================================================================*
|
||||||
|
* Local *
|
||||||
|
*============================================================================*/
|
||||||
|
struct _Eina_Module
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
unsigned int magic;
|
||||||
|
#endif
|
||||||
|
void *handle;
|
||||||
|
char *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MODULE_EXTENSION ".so"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _Dir_List_Get_Cb_Data
|
||||||
|
{
|
||||||
|
Eina_Module_Cb cb;
|
||||||
|
void *data;
|
||||||
|
Eina_List *list;
|
||||||
|
} Dir_List_Get_Cb_Data;
|
||||||
|
|
||||||
|
typedef struct _Dir_List_Cb_Data
|
||||||
|
{
|
||||||
|
Eina_Module_Cb cb;
|
||||||
|
void *data;
|
||||||
|
} Dir_List_Cb_Data;
|
||||||
|
|
||||||
|
static int _dir_list_get_cb(Eina_Module *m, void *data)
|
||||||
|
{
|
||||||
|
Dir_List_Get_Cb_Data *cb_data = data;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
if (cb_data->cb)
|
||||||
|
{
|
||||||
|
ret = cb_data->cb(m, cb_data->data);
|
||||||
|
}
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
cb_data->list = eina_list_append(cb_data->list, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _dir_list_cb(const char *name, const char *path, void *data)
|
||||||
|
{
|
||||||
|
Dir_List_Cb_Data *cb_data = data;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
length = strlen(name);
|
||||||
|
if (length < strlen(MODULE_EXTENSION) + 1) /* x.so */
|
||||||
|
return;
|
||||||
|
if (!strcmp(name + length - strlen(MODULE_EXTENSION),
|
||||||
|
MODULE_EXTENSION))
|
||||||
|
{
|
||||||
|
char file[PATH_MAX];
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
snprintf(file, PATH_MAX, "%s/%s", path, name);
|
||||||
|
m = eina_module_new(file);
|
||||||
|
if (!m)
|
||||||
|
return;
|
||||||
|
/* call the user provided cb on this module */
|
||||||
|
cb_data->cb(m, cb_data->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
/**
|
||||||
|
* Calls the cb function for every module found on the directory path
|
||||||
|
*
|
||||||
|
* @param path The directory's path to search for modules
|
||||||
|
* @param recursive Iterate recursively on the path
|
||||||
|
* @param cb Callback function to call
|
||||||
|
* @param data Data passed to the callback function
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_list(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data)
|
||||||
|
{
|
||||||
|
Dir_List_Cb_Data cb_data;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
|
||||||
|
cb_data.cb = cb;
|
||||||
|
cb_data.data = data;
|
||||||
|
eina_file_dir_list(path, recursive, &_dir_list_cb, &cb_data);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gets a list of modules found on the directory path
|
||||||
|
*
|
||||||
|
* @param path The directory's path to search for modules
|
||||||
|
* @param recursive Iterate recursively on the path
|
||||||
|
* @param cb Callback function to call, if the return value of the callback is zero
|
||||||
|
* it won't be added to the list, if it is one, it will.
|
||||||
|
* @param data Data passed to the callback function
|
||||||
|
*/
|
||||||
|
EAPI Eina_List * eina_module_list_get(const char *path, unsigned int recursive, Eina_Module_Cb cb, void *data)
|
||||||
|
{
|
||||||
|
Dir_List_Get_Cb_Data list_get_cb_data;
|
||||||
|
Dir_List_Cb_Data list_cb_data;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
|
||||||
|
list_get_cb_data.list = NULL;
|
||||||
|
list_get_cb_data.cb = cb;
|
||||||
|
list_get_cb_data.data = data;
|
||||||
|
|
||||||
|
list_cb_data.cb = &_dir_list_get_cb;
|
||||||
|
list_cb_data.data = &list_get_cb_data;
|
||||||
|
|
||||||
|
eina_file_dir_list(path, recursive, &_dir_list_cb, &list_cb_data);
|
||||||
|
|
||||||
|
return list_get_cb_data.list;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Load every module on the list of modules
|
||||||
|
* @param list The list of modules
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_list_load(Eina_List *list)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
for (l = list; l; l = eina_list_next(l))
|
||||||
|
{
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
m = eina_list_data(l);
|
||||||
|
eina_module_load(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_list_unload(Eina_List *list)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
for (l = list; l; l = eina_list_next(l))
|
||||||
|
{
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
m = eina_list_data(l);
|
||||||
|
eina_module_unload(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Helper function that iterates over the list of modules and calls
|
||||||
|
* eina_module_delete on each
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_list_free(Eina_List *list)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
|
||||||
|
for (l = list; l; l = eina_list_next(l))
|
||||||
|
{
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
m = eina_list_data(l);
|
||||||
|
eina_module_free(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI int eina_module_load(Eina_Module *m)
|
||||||
|
{
|
||||||
|
void *dl_handle;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
if (m->handle) return 1;
|
||||||
|
|
||||||
|
dl_handle = dlopen(m->file, RTLD_LAZY);
|
||||||
|
if (!dl_handle) return 0;
|
||||||
|
|
||||||
|
m->handle = dl_handle;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI Eina_Module * eina_module_new(const char *file)
|
||||||
|
{
|
||||||
|
Eina_Module *m;
|
||||||
|
|
||||||
|
assert(file);
|
||||||
|
/* TODO check that the file exists */
|
||||||
|
|
||||||
|
m = malloc(sizeof(Eina_Module));
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO add the magic */
|
||||||
|
#endif
|
||||||
|
m->file = strdup(file);
|
||||||
|
m->handle = NULL;
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_free(Eina_Module *m)
|
||||||
|
{
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO check the magic */
|
||||||
|
#endif
|
||||||
|
if (m->handle)
|
||||||
|
eina_module_unload(m);
|
||||||
|
free(m->file);
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void eina_module_unload(Eina_Module *m)
|
||||||
|
{
|
||||||
|
assert(m);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO check the magic */
|
||||||
|
#endif
|
||||||
|
if (!m->handle)
|
||||||
|
return;
|
||||||
|
dlclose(m->handle);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI void * eina_module_symbol_get(Eina_Module *m, const char *symbol)
|
||||||
|
{
|
||||||
|
assert(m);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO check the magic */
|
||||||
|
#endif
|
||||||
|
return dlsym(m->handle, symbol);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI char * eina_module_path_get(Eina_Module *m)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO check the magic */
|
||||||
|
#endif
|
||||||
|
eina_file_path_nth_get(m->file, -1, &path, NULL);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To be documented
|
||||||
|
* FIXME: To be fixed
|
||||||
|
*/
|
||||||
|
EAPI char * eina_module_name_get(Eina_Module *m)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
#ifdef DEBUG
|
||||||
|
/* TODO check the magic */
|
||||||
|
#endif
|
||||||
|
eina_file_path_nth_get(m->file, -1, NULL, &name);
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* eina_value.c
|
||||||
|
|
||||||
|
Copyright (C) 2001 Christopher Rosendahl <smugg@fatelabs.com>
|
||||||
|
Nathan Ingersoll <ningerso@d.umn.edu>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies of the Software and its documentation and acknowledgment shall be
|
||||||
|
given in the documentation and software packages that this Software was
|
||||||
|
used.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
EAPI const unsigned int eina_prime_table[] =
|
||||||
|
{
|
||||||
|
17, 31, 61, 127, 257, 509, 1021,
|
||||||
|
2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
|
||||||
|
2097143, 4194301, 8388617, 16777213
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void eina_print_warning(const char *function, const char *sparam)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "***** Developer Warning ***** :\n"
|
||||||
|
"\tThis program is calling:\n\n"
|
||||||
|
"\t%s();\n\n"
|
||||||
|
"\tWith the parameter:\n\n"
|
||||||
|
"\t%s\n\n"
|
||||||
|
"\tbeing NULL. Please fix your program.\n", function, sparam);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
SUBDIRS = mm_policies
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = \
|
||||||
|
Makefile.in
|
|
@ -0,0 +1,23 @@
|
||||||
|
MAINTAINERCLEANFILES = \
|
||||||
|
Makefile.in
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I. \
|
||||||
|
-I$(top_srcdir)/src/include
|
||||||
|
|
||||||
|
controllerdir = $(libdir)/eina/mm_policies
|
||||||
|
controller_LTLIBRARIES = fixed.la ememoa.la
|
||||||
|
|
||||||
|
fixed_la_SOURCES = \
|
||||||
|
fixed.c
|
||||||
|
|
||||||
|
fixed_la_LIBADD = $(top_builddir)/src/lib/libeina.la
|
||||||
|
fixed_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||||
|
fixed_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la
|
||||||
|
|
||||||
|
ememoa_la_SOURCES = \
|
||||||
|
ememoa.c
|
||||||
|
|
||||||
|
ememoa_la_LIBADD = $(top_builddir)/src/lib/libeina.la
|
||||||
|
ememoa_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
|
||||||
|
ememoa_la_DEPENDENCIES = $(top_builddir)/src/lib/libeina.la
|
|
@ -0,0 +1,830 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
#include "mempool_struct.h"
|
||||||
|
/*============================================================================*
|
||||||
|
* Local *
|
||||||
|
*============================================================================*/
|
||||||
|
#define EMEMOA_MAGIC 0xDEAD5007
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define EMEMOA_CHECK_MAGIC(Memory) \
|
||||||
|
assert(Memory->magic == EMEMOA_MAGIC);
|
||||||
|
#else
|
||||||
|
#define EMEMOA_CHECK_MAGIC(Memory) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int total = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Ememoa_Mempool_Base_64m Static buffer allocator.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global context for the static buffer allocator.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_64m
|
||||||
|
* TODO this context is mempool relative
|
||||||
|
*/
|
||||||
|
//static struct ememoa_memory_base_s *base_64m = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an item from the base_64m free block list.
|
||||||
|
*
|
||||||
|
* @param index Item to be removed.
|
||||||
|
* @return Will never fail.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_64m
|
||||||
|
*/
|
||||||
|
static void ememoa_memory_base_remove_from_list(struct ememoa_memory_base_s *base_64m, uint16_t index)
|
||||||
|
{
|
||||||
|
uint16_t prev = base_64m->chunks[index].prev;
|
||||||
|
uint16_t next = base_64m->chunks[index].next;
|
||||||
|
|
||||||
|
if (prev != 0xFFFF)
|
||||||
|
base_64m->chunks[prev].next = next;
|
||||||
|
if (next != 0xFFFF)
|
||||||
|
base_64m->chunks[next].prev = prev;
|
||||||
|
if (base_64m->start == index)
|
||||||
|
base_64m->start = next;
|
||||||
|
if (base_64m->over == index)
|
||||||
|
base_64m->over = prev;
|
||||||
|
|
||||||
|
base_64m->chunks[index].prev = 0xFFFF;
|
||||||
|
base_64m->chunks[index].next = 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert an item in the base_64m free block list.
|
||||||
|
*
|
||||||
|
* @param index Item to be inserted.
|
||||||
|
* @return Will break completely if the item is already in the list.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_64m
|
||||||
|
*/
|
||||||
|
static void ememoa_memory_base_insert_in_list(struct ememoa_memory_base_s *base_64m, uint16_t index)
|
||||||
|
{
|
||||||
|
uint16_t length = base_64m->chunks[index].length;
|
||||||
|
uint16_t prev = 0xFFFF;
|
||||||
|
uint16_t next;
|
||||||
|
|
||||||
|
if (base_64m->chunks[index].start == 0xFFFF)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (next = base_64m->start; next != 0xFFFF
|
||||||
|
&& base_64m->chunks[next].length > length; next
|
||||||
|
= base_64m->chunks[next].next)
|
||||||
|
prev = next;
|
||||||
|
|
||||||
|
assert(index != next);
|
||||||
|
assert(index != prev);
|
||||||
|
|
||||||
|
base_64m->chunks[index].next = next;
|
||||||
|
base_64m->chunks[index].prev = prev;
|
||||||
|
|
||||||
|
if (next != 0xFFFF)
|
||||||
|
base_64m->chunks[next].prev = index;
|
||||||
|
else
|
||||||
|
base_64m->over = index;
|
||||||
|
|
||||||
|
if (prev != 0xFFFF)
|
||||||
|
base_64m->chunks[prev].next = index;
|
||||||
|
else
|
||||||
|
base_64m->start = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge two chunk of memory together. Choose the index of the resulting
|
||||||
|
* chunk as the one requiring less effort for committing the change. No
|
||||||
|
* requirement on parameters order or any other characteristic exist.
|
||||||
|
*
|
||||||
|
* @param one First part of the chunk to be merged.
|
||||||
|
* @param two Second part of the chunk to be merged.
|
||||||
|
* @return Index of the new chunk.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_64m
|
||||||
|
*/
|
||||||
|
static uint16_t ememoa_memory_base_merge_64m(struct ememoa_memory_base_s *base_64m, uint16_t one, uint16_t two)
|
||||||
|
{
|
||||||
|
uint16_t index;
|
||||||
|
uint16_t tmp;
|
||||||
|
|
||||||
|
if (base_64m->chunks[one].length < base_64m->chunks[two].length)
|
||||||
|
{
|
||||||
|
tmp = one;
|
||||||
|
one = two;
|
||||||
|
two = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All page refering to 'two' now refere to 'one'. */
|
||||||
|
for (index = base_64m->chunks[two].start; index
|
||||||
|
!= base_64m->chunks[two].end; ++index)
|
||||||
|
base_64m->pages[index] = one;
|
||||||
|
base_64m->pages[index] = one;
|
||||||
|
|
||||||
|
if (base_64m->chunks[one].start < base_64m->chunks[two].start)
|
||||||
|
base_64m->chunks[one].end = base_64m->chunks[two].end;
|
||||||
|
else
|
||||||
|
base_64m->chunks[one].start = base_64m->chunks[two].start;
|
||||||
|
|
||||||
|
base_64m->chunks[one].length += base_64m->chunks[two].length;
|
||||||
|
|
||||||
|
base_64m->chunks[two].start = 0xFFFF;
|
||||||
|
base_64m->chunks[two].use = 0;
|
||||||
|
if (base_64m->jump > two)
|
||||||
|
base_64m->jump = two;
|
||||||
|
|
||||||
|
return one;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a chunk in two, allocating a new one on the fly and doing as few as possible
|
||||||
|
* memory update. The new allocated chunk could be used as the left or right part of
|
||||||
|
* the splitted chunk depending on the fastest strategie. You will need to guess by your
|
||||||
|
* self what was our choice.
|
||||||
|
*
|
||||||
|
* @param index The item to split.
|
||||||
|
* @param length The required size for one of the two resulting chunk.
|
||||||
|
* @return 0xFFFF, if the chunk already has the right size otherwise the new allocated chunk.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_64m
|
||||||
|
*/
|
||||||
|
static uint16_t ememoa_memory_base_split_64m(struct ememoa_memory_base_s *base_64m, uint16_t index, unsigned int length)
|
||||||
|
{
|
||||||
|
if (base_64m->chunks[index].length != length)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_chunck_s a;
|
||||||
|
struct ememoa_memory_base_chunck_s b;
|
||||||
|
uint16_t i;
|
||||||
|
uint16_t splitted;
|
||||||
|
|
||||||
|
while (!(base_64m->chunks[base_64m->jump].start == 0xFFFF
|
||||||
|
&& base_64m->chunks[base_64m->jump].prev
|
||||||
|
== 0xFFFF
|
||||||
|
&& base_64m->chunks[base_64m->jump].next
|
||||||
|
== 0xFFFF))
|
||||||
|
base_64m->jump++;
|
||||||
|
|
||||||
|
splitted = base_64m->jump++;
|
||||||
|
ememoa_memory_base_remove_from_list(base_64m, index);
|
||||||
|
|
||||||
|
a = base_64m->chunks[index];
|
||||||
|
|
||||||
|
b.length = a.length - length;
|
||||||
|
b.end = a.end;
|
||||||
|
b.start = a.start + length;
|
||||||
|
b.next = 0xFFFF;
|
||||||
|
b.prev = 0xFFFF;
|
||||||
|
b.use = 0;
|
||||||
|
|
||||||
|
a.length = length;
|
||||||
|
a.end = a.start + length - 1;
|
||||||
|
a.use = 1;
|
||||||
|
|
||||||
|
if (a.length < b.length)
|
||||||
|
{
|
||||||
|
base_64m->chunks[index] = b;
|
||||||
|
base_64m->chunks[splitted] = a;
|
||||||
|
ememoa_memory_base_insert_in_list(base_64m, index);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
base_64m->chunks[index] = a;
|
||||||
|
base_64m->chunks[splitted] = b;
|
||||||
|
ememoa_memory_base_insert_in_list(base_64m, splitted);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = base_64m->chunks[splitted].start; i
|
||||||
|
!= base_64m->chunks[splitted].end; ++i)
|
||||||
|
base_64m->pages[i] = splitted;
|
||||||
|
base_64m->pages[i] = splitted;
|
||||||
|
|
||||||
|
return splitted;
|
||||||
|
}
|
||||||
|
return 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Ememoa_Mempool_Base_Resize_List Function enabling manipulation of array with linked list properties.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define RESIZE_POOL_SIZE 128
|
||||||
|
struct ememoa_memory_base_resize_list_pool_s {
|
||||||
|
struct ememoa_memory_base_resize_list_pool_s *next;
|
||||||
|
|
||||||
|
unsigned int count;
|
||||||
|
#ifdef USE64
|
||||||
|
uint64_t map[2];
|
||||||
|
#else
|
||||||
|
uint32_t map[4];
|
||||||
|
#endif
|
||||||
|
struct ememoa_memory_base_resize_list_s array[RESIZE_POOL_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ememoa_memory_base_resize_list_pool_s *resize_pool = NULL;
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a new resizable list (it's an array now). It currently use to much memory
|
||||||
|
* when using the base_64m allocator, it could be fixed if really usefull (Not high priority at this time).
|
||||||
|
*
|
||||||
|
* @param size items size inside the list.
|
||||||
|
* @return Will return a pointer to the base array.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
struct ememoa_memory_base_resize_list_s* ememoa_memory_base_resize_list_new(
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_resize_list_s *tmp;
|
||||||
|
struct ememoa_memory_base_resize_list_pool_s *over;
|
||||||
|
unsigned int i;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (over = resize_pool; over && over->count == RESIZE_POOL_SIZE; over
|
||||||
|
= over->next)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!over)
|
||||||
|
{
|
||||||
|
over
|
||||||
|
= ememoa_memory_base_alloc(sizeof(struct ememoa_memory_base_resize_list_pool_s));
|
||||||
|
if (!over)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
over->next = resize_pool;
|
||||||
|
over->count = 0;
|
||||||
|
|
||||||
|
#ifdef USE64
|
||||||
|
for (i = 0; i < 2; ++i)
|
||||||
|
#else
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
#endif
|
||||||
|
over->map[i] = ~0;
|
||||||
|
|
||||||
|
resize_pool = over;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE64
|
||||||
|
for (i = 0, pos = 0; i < 2 && pos == 0; ++i)
|
||||||
|
#else
|
||||||
|
for (i = 0, pos = 0; i < 4 && pos == 0; ++i)
|
||||||
|
#endif
|
||||||
|
#ifdef USE64
|
||||||
|
pos = ffsll (over->map[i]);
|
||||||
|
#else
|
||||||
|
pos = ffs(over->map[i]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
over->count++;
|
||||||
|
pos--;
|
||||||
|
i--;
|
||||||
|
|
||||||
|
#ifdef USE64
|
||||||
|
assert(i >= 0 && i < 2);
|
||||||
|
assert(pos >= 0 && pos < 64);
|
||||||
|
tmp = over->array + pos + i * 64;
|
||||||
|
#else
|
||||||
|
assert(i >= 0 && i < 4);
|
||||||
|
assert(pos >= 0 && pos < 32);
|
||||||
|
tmp = over->array + pos + i * 32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
over->map[i] &= ~(1 << pos);
|
||||||
|
|
||||||
|
bzero(tmp, sizeof(struct ememoa_memory_base_resize_list_s));
|
||||||
|
tmp->size = size;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
tmp->magic = EMEMOA_MAGIC;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Clean a list and all it's item.
|
||||||
|
*
|
||||||
|
* @param base List
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
void ememoa_memory_base_resize_list_clean(
|
||||||
|
struct ememoa_memory_base_resize_list_s* base)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_resize_list_pool_s *over;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (!base)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
ememoa_memory_base_free(base->pool);
|
||||||
|
ememoa_memory_base_free(base->bitmap);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (base->actif != 0)
|
||||||
|
fprintf(stderr, "Warning some element where not freed from this list.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
base->magic = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (over = resize_pool; over && !(over->array <= base && base
|
||||||
|
< over->array + RESIZE_POOL_SIZE); over = over->next)
|
||||||
|
;
|
||||||
|
|
||||||
|
assert(over != NULL);
|
||||||
|
|
||||||
|
index = base - over->array;
|
||||||
|
|
||||||
|
#ifdef USE64
|
||||||
|
over->map[index / 64] |= (1 << (index % 64));
|
||||||
|
#else
|
||||||
|
over->map[index / 32] |= (1 << (index % 32));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* Allocate a new item in the list "base".
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @return Will return the new item index.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
int ememoa_memory_base_resize_list_new_item(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (base == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
if (base->count < base->actif + 1)
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
uint32_t *tmp_bitmap;
|
||||||
|
void *tmp_pool;
|
||||||
|
|
||||||
|
count = base->count + 32;
|
||||||
|
|
||||||
|
tmp_pool = ememoa_memory_base_realloc(base->pool, count
|
||||||
|
* base->size);
|
||||||
|
if (!tmp_pool)
|
||||||
|
return -1;
|
||||||
|
base->pool = tmp_pool;
|
||||||
|
|
||||||
|
tmp_bitmap = ememoa_memory_base_realloc(base->bitmap, (count
|
||||||
|
>> 5) * sizeof(uint32_t));
|
||||||
|
if (!tmp_bitmap)
|
||||||
|
return -1;
|
||||||
|
base->bitmap = tmp_bitmap;
|
||||||
|
|
||||||
|
base->bitmap[base->count >> 5] = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
memset ((uint8_t*) tmp_pool + base->count * base->size, 43, base->size * 32);
|
||||||
|
#endif
|
||||||
|
base->count = count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; base->jump < (base->count >> 5) && base->bitmap[base->jump] == 0; ++base->jump)
|
||||||
|
;
|
||||||
|
|
||||||
|
assert(base->jump < (base->count >> 5));
|
||||||
|
|
||||||
|
i = ffs(base->bitmap[base->jump]) - 1;
|
||||||
|
|
||||||
|
assert(i >= 0 && i < 32);
|
||||||
|
|
||||||
|
base->bitmap[base->jump] &= ~(1 << i);
|
||||||
|
base->actif++;
|
||||||
|
|
||||||
|
return (base->jump << 5) + i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Give the pointer corresponding to an item index.
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @param index Item index given by ememoa_memory_base_resize_list_new_item.
|
||||||
|
* @return Will return a pointer to the item.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
void* ememoa_memory_base_resize_list_get_item(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base, int index)
|
||||||
|
{
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (void*) ((uint8_t*) base->pool + index * base->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give back an item to the list.
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @param index Item index given by ememoa_memory_base_resize_list_new_item.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
void ememoa_memory_base_resize_list_back(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base, int index)
|
||||||
|
{
|
||||||
|
unsigned int shift;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shift = index >> 5;
|
||||||
|
i = index & 0x1F;
|
||||||
|
|
||||||
|
base->bitmap[shift] |= (1 << i);
|
||||||
|
base->actif--;
|
||||||
|
|
||||||
|
if (shift < base->jump)
|
||||||
|
base->jump = shift;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
memset ((uint8_t*) base->pool + base->size * index, 44, base->size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* Make some attempt to resize the size of the list.
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @return Will 0 is nothing where freed, -1 if not enought memory
|
||||||
|
* is available for the operation and anything else if successfull.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
int ememoa_memory_base_resize_list_garbage_collect(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base)
|
||||||
|
{
|
||||||
|
uint32_t *tmp_bitmap;
|
||||||
|
void *tmp_pool;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
count = base->count;
|
||||||
|
|
||||||
|
for (; base->count > 0 && base->bitmap[(base->count >> 5)] == 0xFFFFFFFF; base->count -= 32)
|
||||||
|
;
|
||||||
|
|
||||||
|
tmp_pool = ememoa_memory_base_realloc(base->pool, base->count
|
||||||
|
* base->size);
|
||||||
|
if (!tmp_pool)
|
||||||
|
return -1;
|
||||||
|
base->pool = tmp_pool;
|
||||||
|
|
||||||
|
tmp_bitmap = ememoa_memory_base_realloc(base->bitmap,
|
||||||
|
(base->count >> 5) * sizeof(uint32_t));
|
||||||
|
if (!tmp_bitmap)
|
||||||
|
return -1;
|
||||||
|
base->bitmap = tmp_bitmap;
|
||||||
|
|
||||||
|
return count != base->count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Call fct on all allocated item of the list and return the sum of fct result.
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @param start Index to start at.
|
||||||
|
* @param end Index to end the walk.
|
||||||
|
* @param fct The callback function.
|
||||||
|
* @param ctx An obscure pointer that will be directly passed, without any
|
||||||
|
* check/change to each fct call.
|
||||||
|
* @return Will return the sum of fct result.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
int ememoa_memory_base_resize_list_walk_over(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base, int start,
|
||||||
|
int end, int (*fct)(void *ctx, int index, void *data), void *ctx)
|
||||||
|
{
|
||||||
|
int bitmap;
|
||||||
|
int first;
|
||||||
|
int end_shift;
|
||||||
|
int end_i;
|
||||||
|
int shift;
|
||||||
|
int i;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
i = start & 0x1F;
|
||||||
|
|
||||||
|
if (end < 0)
|
||||||
|
end = base->count - 1;
|
||||||
|
|
||||||
|
if (end == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
end_shift = end >> 5;
|
||||||
|
end_i = end & 0x1F;
|
||||||
|
|
||||||
|
for (shift = start >> 5; shift < end_shift; ++shift)
|
||||||
|
{
|
||||||
|
bitmap = ~base->bitmap[shift];
|
||||||
|
first = ffs(bitmap) - 1;
|
||||||
|
|
||||||
|
i = i > first ? i : first;
|
||||||
|
for (bitmap >>= i; i < 32; ++i, bitmap >>= 1, ++start)
|
||||||
|
if (bitmap & 0x1)
|
||||||
|
result += fct(ctx, start, base->pool + start
|
||||||
|
* base->size);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = ~base->bitmap[shift];
|
||||||
|
for (bitmap >>= i; i < end_i; ++i, bitmap >>= 1, ++start)
|
||||||
|
if (bitmap & 0x1)
|
||||||
|
result += fct(ctx, start, base->pool + start
|
||||||
|
* base->size);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call fct as long as fct doesn't return a value different from 0.
|
||||||
|
*
|
||||||
|
* @param base Pointer to a valid and activ list.
|
||||||
|
* @param start Index to start at.
|
||||||
|
* @param end Index to end the walk.
|
||||||
|
* @param fct The callback function.
|
||||||
|
* @param ctx An obscure pointer that will be directly passed, without any
|
||||||
|
* check/change to each fct call.
|
||||||
|
* @param index If different from NULL, put the index on which we stop in it.
|
||||||
|
* @return Will return a pointer to the item where we stop the search.
|
||||||
|
* @ingroup Ememoa_Mempool_Base_Resize_List
|
||||||
|
*/
|
||||||
|
void* ememoa_memory_base_resize_list_search_over(
|
||||||
|
struct ememoa_memory_base_resize_list_s *base, int start,
|
||||||
|
int end, int (*fct)(void *ctx, int index, void *data), void *ctx,
|
||||||
|
int *index)
|
||||||
|
{
|
||||||
|
int bitmap;
|
||||||
|
int first;
|
||||||
|
int end_shift;
|
||||||
|
int end_i;
|
||||||
|
int shift;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
EMEMOA_CHECK_MAGIC(base);
|
||||||
|
|
||||||
|
i = start & 0x1F;
|
||||||
|
|
||||||
|
if (end < 0)
|
||||||
|
end = base->count - 1;
|
||||||
|
|
||||||
|
if (end == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
end_shift = end >> 5;
|
||||||
|
end_i = end & 0x1F;
|
||||||
|
|
||||||
|
for (shift = start >> 5; shift < end_shift; ++shift)
|
||||||
|
{
|
||||||
|
bitmap = ~base->bitmap[shift];
|
||||||
|
first = ffs(bitmap) - 1;
|
||||||
|
|
||||||
|
i = i > first ? i : first;
|
||||||
|
for (bitmap >>= i; i < 32; ++i, bitmap >>= 1, ++start)
|
||||||
|
if (bitmap & 0x1)
|
||||||
|
if (fct(ctx, start, base->pool + start
|
||||||
|
* base->size))
|
||||||
|
goto found;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = ~base->bitmap[shift];
|
||||||
|
for (bitmap >>= i; i < end_i; ++i, bitmap >>= 1, ++start)
|
||||||
|
if (bitmap & 0x1)
|
||||||
|
if (fct(ctx, start, base->pool + start * base->size))
|
||||||
|
goto found;
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
*index = 0;
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
found: if (index)
|
||||||
|
*index = start;
|
||||||
|
return base->pool + start * base->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ememoa_free(void *data, void *element)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_s *base_64m = data;
|
||||||
|
unsigned int delta = element - base_64m->base;
|
||||||
|
uint16_t index;
|
||||||
|
uint16_t chunk_index;
|
||||||
|
uint16_t prev_chunk_index;
|
||||||
|
uint16_t next_chunk_index;
|
||||||
|
|
||||||
|
if (element == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert(element > base_64m->base);
|
||||||
|
|
||||||
|
index = delta >> 12;
|
||||||
|
chunk_index = base_64m->pages[index];
|
||||||
|
|
||||||
|
total -= base_64m->chunks[chunk_index].length;
|
||||||
|
#ifdef ALLOC_REPORT
|
||||||
|
fprintf(stderr, "free %i [%i] => %p\n", base_64m->chunks[chunk_index].length, total << 12, ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
prev_chunk_index = base_64m->pages[index - 1];
|
||||||
|
next_chunk_index
|
||||||
|
= base_64m->pages[base_64m->chunks[chunk_index].end + 1];
|
||||||
|
|
||||||
|
if (index > 0 && prev_chunk_index < base_64m->chunks_count)
|
||||||
|
if (base_64m->chunks[prev_chunk_index].use == 0)
|
||||||
|
{
|
||||||
|
ememoa_memory_base_remove_from_list(base_64m, prev_chunk_index);
|
||||||
|
chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
|
||||||
|
prev_chunk_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base_64m->chunks[chunk_index].end < base_64m->chunks_count
|
||||||
|
&& next_chunk_index < base_64m->chunks_count)
|
||||||
|
if (base_64m->chunks[next_chunk_index].use == 0)
|
||||||
|
{
|
||||||
|
ememoa_memory_base_remove_from_list(base_64m, next_chunk_index);
|
||||||
|
chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
|
||||||
|
next_chunk_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
ememoa_memory_base_insert_in_list(base_64m, chunk_index);
|
||||||
|
base_64m->chunks[chunk_index].use = 0;
|
||||||
|
}
|
||||||
|
static void * ememoa_alloc(void *data, unsigned int size)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_s *base_64m = data;
|
||||||
|
uint16_t real = (size >> 12) + (size & 0xFFF ? 1 : 0);
|
||||||
|
uint16_t jump = base_64m->start;
|
||||||
|
uint16_t prev = 0xFFFF;
|
||||||
|
|
||||||
|
while (jump != 0xFFFF && base_64m->chunks[jump].length > real)
|
||||||
|
{
|
||||||
|
prev = jump;
|
||||||
|
jump = base_64m->chunks[jump].next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev != 0xFFFF)
|
||||||
|
{
|
||||||
|
uint16_t splitted = ememoa_memory_base_split_64m(base_64m, prev, real);
|
||||||
|
uint16_t allocated;
|
||||||
|
uint16_t empty;
|
||||||
|
|
||||||
|
/* Guess who is who */
|
||||||
|
allocated = base_64m->chunks[prev].use == 1 ? prev : splitted;
|
||||||
|
empty = base_64m->chunks[prev].use == 1 ? splitted : prev;
|
||||||
|
|
||||||
|
total += real;
|
||||||
|
#ifdef ALLOC_REPORT
|
||||||
|
fprintf(stderr, "alloc %i(%i) [%i] => %p\n", real << 12, size, total << 12, ((uint8_t*) base_64m->base) + (base_64m->chunks[allocated].start << 12));
|
||||||
|
#endif
|
||||||
|
return ((uint8_t*) base_64m->base)
|
||||||
|
+ (base_64m->chunks[allocated].start << 12);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *ememoa_realloc(void *data, void *element, unsigned int size)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_s *base_64m = data;
|
||||||
|
void* tmp;
|
||||||
|
unsigned int delta = element - base_64m->base;
|
||||||
|
uint16_t real = (size >> 12) + (size & 0xFFF ? 1 : 0);
|
||||||
|
uint16_t index;
|
||||||
|
uint16_t chunk_index;
|
||||||
|
uint16_t next_chunk_index;
|
||||||
|
|
||||||
|
if (element == NULL)
|
||||||
|
return ememoa_alloc(base_64m, size);
|
||||||
|
|
||||||
|
assert(element > base_64m->base);
|
||||||
|
|
||||||
|
index = delta >> 12;
|
||||||
|
chunk_index = base_64m->pages[index];
|
||||||
|
|
||||||
|
/* FIXME: Not resizing when the size is big enough */
|
||||||
|
if (real <= base_64m->chunks[chunk_index].length)
|
||||||
|
return element;
|
||||||
|
|
||||||
|
next_chunk_index
|
||||||
|
= base_64m->pages[base_64m->chunks[chunk_index].end + 1];
|
||||||
|
|
||||||
|
if (base_64m->chunks[next_chunk_index].use == 0)
|
||||||
|
if (real <= base_64m->chunks[next_chunk_index].length
|
||||||
|
+ base_64m->chunks[chunk_index].length)
|
||||||
|
{
|
||||||
|
uint16_t splitted;
|
||||||
|
uint16_t allocated;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
total -= base_64m->chunks[chunk_index].length;
|
||||||
|
tmp = base_64m->chunks[chunk_index].length;
|
||||||
|
|
||||||
|
ememoa_memory_base_remove_from_list(base_64m, next_chunk_index);
|
||||||
|
chunk_index = ememoa_memory_base_merge_64m(base_64m, chunk_index,
|
||||||
|
next_chunk_index);
|
||||||
|
splitted = ememoa_memory_base_split_64m(base_64m, chunk_index,
|
||||||
|
real);
|
||||||
|
|
||||||
|
allocated
|
||||||
|
= base_64m->chunks[chunk_index].use
|
||||||
|
== 1 ? chunk_index
|
||||||
|
: splitted;
|
||||||
|
|
||||||
|
ememoa_memory_base_remove_from_list(base_64m, allocated);
|
||||||
|
|
||||||
|
total += real;
|
||||||
|
#ifdef ALLOC_REPORT
|
||||||
|
fprintf(stderr, "realloc %i(%i) [%i] => %p\n", (real - tmp) << 12, size, total << 12, ((uint8_t*) base_64m->base) + (base_64m->chunks[allocated].start << 12));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ((uint8_t*) base_64m->base)
|
||||||
|
+ (base_64m->chunks[allocated].start
|
||||||
|
<< 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = ememoa_alloc(base_64m, size);
|
||||||
|
if (!tmp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(tmp, element, base_64m->chunks[chunk_index].length << 12);
|
||||||
|
ememoa_memory_base_free_64m(element);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *ememoa_init(void *buffer, unsigned int size, const char *options, va_list args)
|
||||||
|
{
|
||||||
|
struct ememoa_memory_base_s *new_64m = buffer;
|
||||||
|
unsigned int temp_size;
|
||||||
|
|
||||||
|
temp_size = (size - sizeof(struct ememoa_memory_base_s)) >> 12;
|
||||||
|
if (temp_size <= 1)
|
||||||
|
{
|
||||||
|
/* TODO handle an error */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
new_64m->magic = EMEMOA_MAGIC;
|
||||||
|
#endif
|
||||||
|
new_64m->chunks
|
||||||
|
= (struct ememoa_memory_base_chunck_s*) ((struct ememoa_memory_base_s*) new_64m
|
||||||
|
+ 1);
|
||||||
|
new_64m->pages
|
||||||
|
= (uint16_t*)((struct ememoa_memory_base_chunck_s*) new_64m->chunks
|
||||||
|
+ temp_size + 1);
|
||||||
|
new_64m->base = ((uint16_t*) new_64m->pages + temp_size + 1);
|
||||||
|
new_64m->start = 0;
|
||||||
|
|
||||||
|
new_64m->chunks_count
|
||||||
|
= (size - sizeof(struct ememoa_memory_base_s)
|
||||||
|
- temp_size
|
||||||
|
* (sizeof(struct ememoa_memory_base_chunck_s)
|
||||||
|
+ sizeof(uint16_t)))
|
||||||
|
/ 4096;
|
||||||
|
|
||||||
|
memset(new_64m->chunks, 0xFF,
|
||||||
|
sizeof(struct ememoa_memory_base_chunck_s) * temp_size);
|
||||||
|
memset(new_64m->pages, 0, sizeof(uint16_t) * temp_size);
|
||||||
|
|
||||||
|
new_64m->chunks[0].start = 0;
|
||||||
|
new_64m->chunks[0].end = new_64m->chunks_count - 1;
|
||||||
|
new_64m->chunks[0].length = new_64m->chunks_count;
|
||||||
|
new_64m->chunks[0].next = 0xFFFF;
|
||||||
|
new_64m->chunks[0].prev = 0xFFFF;
|
||||||
|
new_64m->chunks[0].use = 0;
|
||||||
|
new_64m->over = 0;
|
||||||
|
new_64m->start = 0;
|
||||||
|
new_64m->jump = 1;
|
||||||
|
|
||||||
|
return new_64m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ememoa_shutdown(void *data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
/*============================================================================*
|
||||||
|
* API *
|
||||||
|
*============================================================================*/
|
||||||
|
Eina_Mempool_Backend mp_backend = {
|
||||||
|
.init = &ememoa_init,
|
||||||
|
.shutdown = &ememoa_shutdown,
|
||||||
|
.realloc = &ememoa_realloc,
|
||||||
|
.alloc = &ememoa_alloc,
|
||||||
|
.free = &ememoa_free,
|
||||||
|
};
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
** Copyright Cedric BAIL, 2006
|
||||||
|
** contact: cedric.bail@free.fr
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMEMOA_MEMORY_BASE_H__
|
||||||
|
# define EMEMOA_MEMORY_BASE_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct ememoa_memory_base_resize_list_s
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
unsigned int magic;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *pool;
|
||||||
|
uint32_t *bitmap;
|
||||||
|
|
||||||
|
unsigned int jump;
|
||||||
|
unsigned int count;
|
||||||
|
unsigned int actif;
|
||||||
|
unsigned int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Direct use of this two function is most of the time a bad idea. */
|
||||||
|
//extern void* (*ememoa_memory_base_alloc)(unsigned int size);
|
||||||
|
//extern void (*ememoa_memory_base_free)(void *ptr);
|
||||||
|
//extern void* (*ememoa_memory_base_realloc)(void* ptr, unsigned int size);
|
||||||
|
|
||||||
|
int ememoa_memory_base_init_64m(void* buffer, unsigned int size);
|
||||||
|
|
||||||
|
struct ememoa_memory_base_resize_list_s* ememoa_memory_base_resize_list_new (unsigned int size);
|
||||||
|
void ememoa_memory_base_resize_list_clean (struct ememoa_memory_base_resize_list_s* base);
|
||||||
|
int ememoa_memory_base_resize_list_new_item (struct ememoa_memory_base_resize_list_s *base);
|
||||||
|
void* ememoa_memory_base_resize_list_get_item (struct ememoa_memory_base_resize_list_s *base, int index);
|
||||||
|
void ememoa_memory_base_resize_list_back (struct ememoa_memory_base_resize_list_s *base, int index);
|
||||||
|
int ememoa_memory_base_resize_list_walk_over (struct ememoa_memory_base_resize_list_s *base,
|
||||||
|
int start,
|
||||||
|
int end,
|
||||||
|
int (*fct)(void *ctx, int index, void *data),
|
||||||
|
void *ctx);
|
||||||
|
void* ememoa_memory_base_resize_list_search_over (struct ememoa_memory_base_resize_list_s *base,
|
||||||
|
int start,
|
||||||
|
int end,
|
||||||
|
int (*fct)(void *ctx, int index, void *data),
|
||||||
|
void *ctx,
|
||||||
|
int *index);
|
||||||
|
|
||||||
|
/* Be carefull when you call this function, you will loose all index mapping after this call. */
|
||||||
|
int ememoa_memory_base_resize_list_garbage_collect (struct ememoa_memory_base_resize_list_s *base);
|
||||||
|
|
||||||
|
#endif /* EMEMOA_MEMORY_BASE_H__ */
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
** Copyright Cedric BAIL, 2006
|
||||||
|
** contact: cedric.bail@free.fr
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMEMOA_MEMPOOL_ERROR_H__
|
||||||
|
# define EMEMOA_MEMPOOL_ERROR_H__
|
||||||
|
|
||||||
|
typedef enum _ememoa_mempool_error_e
|
||||||
|
{
|
||||||
|
EMEMOA_NO_ERROR,
|
||||||
|
EMEMOA_ERROR_INIT_ALREADY_DONE,
|
||||||
|
EMEMOA_ERROR_REALLOC_AVAILABLE_OBJECTS_FAILED,
|
||||||
|
EMEMOA_ERROR_REALLOC_OBJECTS_USE_FAILED,
|
||||||
|
EMEMOA_ERROR_REALLOC_JUMP_OBJECT_FAILED,
|
||||||
|
EMEMOA_ERROR_REALLOC_OBJECTS_POOL_FAILED,
|
||||||
|
EMEMOA_ERROR_MALLOC_NEW_POOL,
|
||||||
|
EMEMOA_ERROR_PUSH_ADDRESS_NOT_FOUND,
|
||||||
|
EMEMOA_NO_EMPTY_POOL,
|
||||||
|
EMEMOA_DOUBLE_PUSH,
|
||||||
|
EMEMOA_NO_MORE_MEMORY,
|
||||||
|
EMEMOA_INVALID_MEMPOOL
|
||||||
|
} ememoa_mempool_error_t;
|
||||||
|
|
||||||
|
const char*
|
||||||
|
ememoa_mempool_error2string (ememoa_mempool_error_t error_code);
|
||||||
|
|
||||||
|
#endif /* EMEMOA_MEMPOOL_ERROR_H__ */
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "Eina.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
|
static void push(void *data, void *element)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
static void * pop(void *data, unsigned int size)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *init(unsigned int size)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown(void *data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Mempool_Backend mp_backend = {
|
||||||
|
.init = &init,
|
||||||
|
.shutdown = &shutdown,
|
||||||
|
.alloc = &pop,
|
||||||
|
.free = &push,
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
** Copyright Cedric BAIL, 2006
|
||||||
|
** contact: cedric.bail@free.fr
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MEMPOOL_STRUCT_H__
|
||||||
|
# define MEMPOOL_STRUCT_H__
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_PTHREAD
|
||||||
|
# include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ememoa_memory_base.h"
|
||||||
|
//#include "ememoa_mempool_error.h"
|
||||||
|
|
||||||
|
struct ememoa_memory_base_chunck_s
|
||||||
|
{
|
||||||
|
uint16_t start;
|
||||||
|
uint16_t end;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
uint16_t next;
|
||||||
|
uint16_t prev;
|
||||||
|
|
||||||
|
uint8_t use;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ememoa_memory_base_s
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
unsigned int magic;
|
||||||
|
#endif
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
struct ememoa_memory_base_chunck_s *chunks;
|
||||||
|
uint16_t *pages;
|
||||||
|
|
||||||
|
unsigned int chunks_count;
|
||||||
|
|
||||||
|
uint16_t start;
|
||||||
|
uint16_t over;
|
||||||
|
uint16_t jump;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MEMPOOL_STRUCT_H__ */
|
Loading…
Reference in New Issue