summaryrefslogtreecommitdiff
path: root/Source/DirectFB/lib/fusion/shm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/lib/fusion/shm')
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/Makefile.am31
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/Makefile.in565
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/fake.c163
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/heap.c802
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/pool.c954
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/pool.h69
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/shm.c337
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/shm.h48
-rwxr-xr-xSource/DirectFB/lib/fusion/shm/shm_internal.h264
9 files changed, 3233 insertions, 0 deletions
diff --git a/Source/DirectFB/lib/fusion/shm/Makefile.am b/Source/DirectFB/lib/fusion/shm/Makefile.am
new file mode 100755
index 0000000..23ed4a5
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/Makefile.am
@@ -0,0 +1,31 @@
+## Makefile.am for DirectFB/lib/fusion/shm
+
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"@DATADIR@\" \
+ -DMODULEDIR=\"@MODULEDIR@\"
+
+if ENABLE_MULTI
+SHMSOURCES = heap.c pool.c shm.c
+else
+SHMSOURCES = fake.c
+endif
+
+EXTRA_DIST = fake.c
+
+noinst_LTLIBRARIES = libfusion_shm.la
+
+libfusion_shm_la_SOURCES = \
+ $(SHMSOURCES)
+
+includedir = @INCLUDEDIR@/fusion/shm
+
+include_HEADERS = \
+ pool.h \
+ shm.h \
+ shm_internal.h
diff --git a/Source/DirectFB/lib/fusion/shm/Makefile.in b/Source/DirectFB/lib/fusion/shm/Makefile.in
new file mode 100755
index 0000000..987fa8f
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/Makefile.in
@@ -0,0 +1,565 @@
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = lib/fusion/shm
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libfusion_shm_la_LIBADD =
+am__libfusion_shm_la_SOURCES_DIST = fake.c heap.c pool.c shm.c
+@ENABLE_MULTI_FALSE@am__objects_1 = fake.lo
+@ENABLE_MULTI_TRUE@am__objects_1 = heap.lo pool.lo shm.lo
+am_libfusion_shm_la_OBJECTS = $(am__objects_1)
+libfusion_shm_la_OBJECTS = $(am_libfusion_shm_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libfusion_shm_la_SOURCES)
+DIST_SOURCES = $(am__libfusion_shm_la_SOURCES_DIST)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(includedir)"
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DFB_CFLAGS_OMIT_FRAME_POINTER = @DFB_CFLAGS_OMIT_FRAME_POINTER@
+DFB_INTERNAL_CFLAGS = @DFB_INTERNAL_CFLAGS@
+DFB_LDFLAGS = @DFB_LDFLAGS@
+DFB_SMOOTH_SCALING = @DFB_SMOOTH_SCALING@
+DIRECTFB_BINARY_AGE = @DIRECTFB_BINARY_AGE@
+DIRECTFB_CSOURCE = @DIRECTFB_CSOURCE@
+DIRECTFB_INTERFACE_AGE = @DIRECTFB_INTERFACE_AGE@
+DIRECTFB_MAJOR_VERSION = @DIRECTFB_MAJOR_VERSION@
+DIRECTFB_MICRO_VERSION = @DIRECTFB_MICRO_VERSION@
+DIRECTFB_MINOR_VERSION = @DIRECTFB_MINOR_VERSION@
+DIRECTFB_VERSION = @DIRECTFB_VERSION@
+DIRECT_BUILD_DEBUG = @DIRECT_BUILD_DEBUG@
+DIRECT_BUILD_DEBUGS = @DIRECT_BUILD_DEBUGS@
+DIRECT_BUILD_GETTID = @DIRECT_BUILD_GETTID@
+DIRECT_BUILD_NETWORK = @DIRECT_BUILD_NETWORK@
+DIRECT_BUILD_STDBOOL = @DIRECT_BUILD_STDBOOL@
+DIRECT_BUILD_TEXT = @DIRECT_BUILD_TEXT@
+DIRECT_BUILD_TRACE = @DIRECT_BUILD_TRACE@
+DSYMUTIL = @DSYMUTIL@
+DYNLIB = @DYNLIB@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+FREETYPE_PROVIDER = @FREETYPE_PROVIDER@
+FUSION_BUILD_KERNEL = @FUSION_BUILD_KERNEL@
+FUSION_BUILD_MULTI = @FUSION_BUILD_MULTI@
+FUSION_MESSAGE_SIZE = @FUSION_MESSAGE_SIZE@
+GIF_PROVIDER = @GIF_PROVIDER@
+GREP = @GREP@
+HAVE_LINUX = @HAVE_LINUX@
+INCLUDEDIR = @INCLUDEDIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTERNALINCLUDEDIR = @INTERNALINCLUDEDIR@
+JPEG_PROVIDER = @JPEG_PROVIDER@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBJPEG = @LIBJPEG@
+LIBOBJS = @LIBOBJS@
+LIBPNG = @LIBPNG@
+LIBPNG_CONFIG = @LIBPNG_CONFIG@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_AGE = @LT_AGE@
+LT_BINARY = @LT_BINARY@
+LT_CURRENT = @LT_CURRENT@
+LT_RELEASE = @LT_RELEASE@
+LT_REVISION = @LT_REVISION@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAN2HTML = @MAN2HTML@
+MKDIR_P = @MKDIR_P@
+MODULEDIR = @MODULEDIR@
+MODULEDIRNAME = @MODULEDIRNAME@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+OSX_LIBS = @OSX_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PNG_PROVIDER = @PNG_PROVIDER@
+RANLIB = @RANLIB@
+RUNTIME_SYSROOT = @RUNTIME_SYSROOT@
+SDL_CFLAGS = @SDL_CFLAGS@
+SDL_LIBS = @SDL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOPATH = @SOPATH@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+SYSFS_LIBS = @SYSFS_LIBS@
+THREADFLAGS = @THREADFLAGS@
+THREADLIB = @THREADLIB@
+TSLIB_CFLAGS = @TSLIB_CFLAGS@
+TSLIB_LIBS = @TSLIB_LIBS@
+VERSION = @VERSION@
+VNC_CFLAGS = @VNC_CFLAGS@
+VNC_CONFIG = @VNC_CONFIG@
+VNC_LIBS = @VNC_LIBS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @INCLUDEDIR@/fusion/shm
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_builddir)/include \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib
+
+AM_CPPFLAGS = \
+ -DDATADIR=\"@DATADIR@\" \
+ -DMODULEDIR=\"@MODULEDIR@\"
+
+@ENABLE_MULTI_FALSE@SHMSOURCES = fake.c
+@ENABLE_MULTI_TRUE@SHMSOURCES = heap.c pool.c shm.c
+EXTRA_DIST = fake.c
+noinst_LTLIBRARIES = libfusion_shm.la
+libfusion_shm_la_SOURCES = \
+ $(SHMSOURCES)
+
+include_HEADERS = \
+ pool.h \
+ shm.h \
+ shm_internal.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/fusion/shm/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu lib/fusion/shm/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfusion_shm.la: $(libfusion_shm_la_OBJECTS) $(libfusion_shm_la_DEPENDENCIES)
+ $(LINK) $(libfusion_shm_la_OBJECTS) $(libfusion_shm_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fake.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shm.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-includeHEADERS install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-includeHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Source/DirectFB/lib/fusion/shm/fake.c b/Source/DirectFB/lib/fusion/shm/fake.c
new file mode 100755
index 0000000..32e25cd
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/fake.c
@@ -0,0 +1,163 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <direct/debug.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+#include <fusion/shm/shm.h>
+#include <fusion/shm/pool.h>
+
+#include <fusion/shm/shm_internal.h>
+
+
+DirectResult
+fusion_shm_pool_create( FusionWorld *world,
+ const char *name,
+ unsigned int max_size,
+ bool debug,
+ FusionSHMPoolShared **ret_pool )
+{
+ FusionSHMPoolShared *pool;
+
+#if !DIRECT_BUILD_DEBUGS
+ debug = false;
+#endif
+
+ pool = D_CALLOC( 1, sizeof(FusionSHMPoolShared) );
+ if (!pool)
+ return D_OOM();
+
+ pool->debug = debug;
+
+ D_MAGIC_SET( pool, FusionSHMPoolShared );
+
+ *ret_pool = pool;
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_destroy( FusionWorld *world,
+ FusionSHMPoolShared *pool )
+{
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_MAGIC_CLEAR( pool );
+
+ D_FREE( pool );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_attach( FusionSHM *shm,
+ FusionSHMPoolShared *pool )
+{
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ pool->index++;
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_detach( FusionSHM *shm,
+ FusionSHMPoolShared *pool )
+{
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_ASSERT( pool->index > 0 );
+
+ pool->index--;
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_allocate( FusionSHMPoolShared *pool,
+ int size,
+ bool clear,
+ bool lock,
+ void **ret_data )
+{
+ void *data;
+
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ data = clear ? D_CALLOC( 1, size ) : D_MALLOC( size );
+ if (!data)
+ return DR_NOSHAREDMEMORY;
+
+ *ret_data = data;
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_reallocate( FusionSHMPoolShared *pool,
+ void *data,
+ int size,
+ bool lock,
+ void **ret_data )
+{
+ void *new_data;
+
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ new_data = D_REALLOC( data, size );
+ if (!new_data)
+ return DR_NOSHAREDMEMORY;
+
+ *ret_data = new_data;
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_deallocate( FusionSHMPoolShared *pool,
+ void *data,
+ bool lock )
+{
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_FREE( data );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_enum_pools( FusionWorld *world,
+ FusionSHMPoolCallback callback,
+ void *ctx )
+{
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/fusion/shm/heap.c b/Source/DirectFB/lib/fusion/shm/heap.c
new file mode 100755
index 0000000..4a76229
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/heap.c
@@ -0,0 +1,802 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/* Heap management adapted from libc
+ Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written May 1989 by Mike Haertel.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+ The author may be reached (Email) at the address mike@ai.mit.edu,
+ or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/conf.h>
+#include <fusion/shmalloc.h>
+#include <fusion/fusion_internal.h>
+
+#include <fusion/shm/pool.h>
+#include <fusion/shm/shm_internal.h>
+
+
+D_DEBUG_DOMAIN( Fusion_SHMHeap, "Fusion/SHMHeap", "Fusion Shared Memory Heap" );
+
+/**********************************************************************************************************************/
+
+/* Aligned allocation. */
+static void *
+align( shmalloc_heap *heap, size_t size )
+{
+ void *result;
+ unsigned long adj;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %zu )\n", __FUNCTION__, heap, size );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ result = __shmalloc_brk( heap, size );
+
+ adj = (unsigned long) result % BLOCKSIZE;
+ if (adj != 0) {
+ adj = BLOCKSIZE - adj;
+ __shmalloc_brk( heap, adj );
+ result = (char *) result + adj;
+ }
+
+ return result;
+}
+
+/* Get neatly aligned memory, initializing or
+ growing the heap info table as necessary. */
+static void *
+morecore( shmalloc_heap *heap, size_t size )
+{
+ void *result;
+ shmalloc_info *newinfo, *oldinfo;
+ size_t newsize;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %zu )\n", __FUNCTION__, heap, size );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ result = align( heap, size );
+ if (result == NULL)
+ return NULL;
+
+ /* Check if we need to grow the info table. */
+ if ((size_t) BLOCK ((char *) result + size) > heap->heapsize) {
+ newsize = heap->heapsize;
+
+ while ((size_t) BLOCK ((char *) result + size) > newsize)
+ newsize *= 2;
+
+ newinfo = (shmalloc_info *) align( heap, newsize * sizeof (shmalloc_info) );
+ if (newinfo == NULL) {
+ __shmalloc_brk( heap, -size );
+ return NULL;
+ }
+
+ direct_memcpy( newinfo, heap->heapinfo,
+ heap->heapsize * sizeof (shmalloc_info) );
+
+ memset (newinfo + heap->heapsize,
+ 0, (newsize - heap->heapsize) * sizeof (shmalloc_info));
+
+ oldinfo = heap->heapinfo;
+
+ newinfo[BLOCK (oldinfo)].busy.type = 0;
+ newinfo[BLOCK (oldinfo)].busy.info.size = BLOCKIFY (heap->heapsize * sizeof (shmalloc_info));
+
+ heap->heapinfo = newinfo;
+
+ _fusion_shfree( heap, oldinfo );
+
+ heap->heapsize = newsize;
+ }
+
+ heap->heaplimit = BLOCK ((char *) result + size);
+
+ return result;
+}
+
+/**********************************************************************************************************************/
+
+/* Allocate memory from the heap. */
+void *
+_fusion_shmalloc( shmalloc_heap *heap, size_t size )
+{
+ void *result;
+ size_t block, blocks, lastblocks, start;
+ register size_t i;
+ struct list *next;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %zu )\n", __FUNCTION__, heap, size );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ /* Some programs will call shmalloc (0). We let them pass. */
+ if (size == 0)
+ return NULL;
+
+ if (size < sizeof (struct list))
+ size = sizeof (struct list);
+
+ /* Determine the allocation policy based on the request size. */
+ if (size <= BLOCKSIZE / 2) {
+ /* Small allocation to receive a fragment of a block.
+ Determine the logarithm to base two of the fragment size. */
+ register size_t log = 1;
+ --size;
+ while ((size /= 2) != 0)
+ ++log;
+
+ /* Look in the fragment lists for a
+ free fragment of the desired size. */
+ next = heap->fraghead[log].next;
+ if (next != NULL) {
+ /* There are free fragments of this size.
+ Pop a fragment out of the fragment list and return it.
+ Update the block's nfree and first counters. */
+ result = (void *) next;
+ next->prev->next = next->next;
+ if (next->next != NULL)
+ next->next->prev = next->prev;
+ block = BLOCK (result);
+ if (--(heap->heapinfo[block].busy.info.frag.nfree) != 0)
+ heap->heapinfo[block].busy.info.frag.first = (unsigned long int)
+ ((unsigned long int) ((char *) next->next - (char *) NULL)
+ % BLOCKSIZE) >> log;
+
+ /* Update the statistics. */
+ heap->chunks_used++;
+ heap->bytes_used += 1 << log;
+ heap->chunks_free--;
+ heap->bytes_free -= 1 << log;
+ }
+ else {
+ /* No free fragments of the desired size, so get a new block
+ and break it into fragments, returning the first. */
+ result = _fusion_shmalloc( heap, BLOCKSIZE );
+ if (result == NULL)
+ return NULL;
+#if 1 /* Adapted from Mike */
+ heap->fragblocks[log]++;
+#endif
+
+ /* Link all fragments but the first into the free list. */
+ for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) {
+ next = (struct list *) ((char *) result + (i << log));
+ next->next = heap->fraghead[log].next;
+ next->prev = &heap->fraghead[log];
+ next->prev->next = next;
+ if (next->next != NULL)
+ next->next->prev = next;
+ }
+
+ /* Initialize the nfree and first counters for this block. */
+ block = BLOCK (result);
+ heap->heapinfo[block].busy.type = log;
+ heap->heapinfo[block].busy.info.frag.nfree = i - 1;
+ heap->heapinfo[block].busy.info.frag.first = i - 1;
+
+ heap->chunks_free += (BLOCKSIZE >> log) - 1;
+ heap->bytes_free += BLOCKSIZE - (1 << log);
+ heap->bytes_used -= BLOCKSIZE - (1 << log);
+ }
+ }
+ else {
+ /* Large allocation to receive one or more blocks.
+ Search the free list in a circle starting at the last place visited.
+ If we loop completely around without finding a large enough
+ space we will have to get more memory from the system. */
+ blocks = BLOCKIFY (size);
+ start = block = heap->heapindex;
+ while (heap->heapinfo[block].free.size < blocks) {
+ block = heap->heapinfo[block].free.next;
+ if (block == start) {
+ /* Need to get more from the system. Check to see if
+ the new core will be contiguous with the final free
+ block; if so we don't need to get as much. */
+ block = heap->heapinfo[0].free.prev;
+ lastblocks = heap->heapinfo[block].free.size;
+ if (heap->heaplimit != 0 && block + lastblocks == heap->heaplimit &&
+ __shmalloc_brk( heap, 0 ) == ADDRESS (block + lastblocks) &&
+ (morecore( heap, (blocks - lastblocks) * BLOCKSIZE) ) != NULL) {
+#if 1 /* Adapted from Mike */
+
+ /* Note that morecore() can change the location of
+ the final block if it moves the info table and the
+ old one gets coalesced into the final block. */
+ block = heap->heapinfo[0].free.prev;
+ heap->heapinfo[block].free.size += blocks - lastblocks;
+#else
+ heap->heapinfo[block].free.size = blocks;
+#endif
+ heap->bytes_free += (blocks - lastblocks) * BLOCKSIZE;
+ continue;
+ }
+ result = morecore( heap, blocks * BLOCKSIZE );
+ if (result == NULL)
+ return NULL;
+ block = BLOCK (result);
+ heap->heapinfo[block].busy.type = 0;
+ heap->heapinfo[block].busy.info.size = blocks;
+ heap->chunks_used++;
+ heap->bytes_used += blocks * BLOCKSIZE;
+ return result;
+ }
+ }
+
+ /* At this point we have found a suitable free list entry.
+ Figure out how to remove what we need from the list. */
+ result = ADDRESS (block);
+ if (heap->heapinfo[block].free.size > blocks) {
+ /* The block we found has a bit left over,
+ so relink the tail end back into the free list. */
+ heap->heapinfo[block + blocks].free.size
+ = heap->heapinfo[block].free.size - blocks;
+ heap->heapinfo[block + blocks].free.next
+ = heap->heapinfo[block].free.next;
+ heap->heapinfo[block + blocks].free.prev
+ = heap->heapinfo[block].free.prev;
+ heap->heapinfo[heap->heapinfo[block].free.prev].free.next
+ = heap->heapinfo[heap->heapinfo[block].free.next].free.prev
+ = heap->heapindex = block + blocks;
+ }
+ else {
+ /* The block exactly matches our requirements,
+ so just remove it from the list. */
+ heap->heapinfo[heap->heapinfo[block].free.next].free.prev
+ = heap->heapinfo[block].free.prev;
+ heap->heapinfo[heap->heapinfo[block].free.prev].free.next
+ = heap->heapindex = heap->heapinfo[block].free.next;
+ heap->chunks_free--;
+ }
+
+ heap->heapinfo[block].busy.type = 0;
+ heap->heapinfo[block].busy.info.size = blocks;
+ heap->chunks_used++;
+ heap->bytes_used += blocks * BLOCKSIZE;
+ heap->bytes_free -= blocks * BLOCKSIZE;
+ }
+
+ return result;
+}
+
+/* Resize the given region to the new size, returning a pointer
+ to the (possibly moved) region. This is optimized for speed;
+ some benchmarks seem to indicate that greater compactness is
+ achieved by unconditionally allocating and copying to a
+ new region. This module has incestuous knowledge of the
+ internals of both free and shmalloc. */
+void *
+_fusion_shrealloc( shmalloc_heap *heap, void *ptr, size_t size )
+{
+ void *result;
+ int type;
+ size_t block, blocks, oldlimit;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %p, %zu )\n", __FUNCTION__, heap, ptr, size );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ if (ptr == NULL)
+ return _fusion_shmalloc( heap, size );
+ else if (size == 0) {
+ _fusion_shfree( heap, ptr );
+ return NULL;
+ }
+
+ block = BLOCK (ptr);
+
+ type = heap->heapinfo[block].busy.type;
+ switch (type) {
+ case 0:
+ /* Maybe reallocate a large block to a small fragment. */
+ if (size <= BLOCKSIZE / 2) {
+ result = _fusion_shmalloc( heap, size );
+ if (result != NULL) {
+ direct_memcpy (result, ptr, size);
+ _fusion_shfree( heap, ptr );
+ return result;
+ }
+ }
+
+ /* The new size is a large allocation as well;
+ see if we can hold it in place. */
+ blocks = BLOCKIFY (size);
+ if (blocks < heap->heapinfo[block].busy.info.size) {
+ /* The new size is smaller; return
+ excess memory to the free list. */
+ heap->heapinfo[block + blocks].busy.type = 0;
+ heap->heapinfo[block + blocks].busy.info.size
+ = heap->heapinfo[block].busy.info.size - blocks;
+ heap->heapinfo[block].busy.info.size = blocks;
+ _fusion_shfree( heap, ADDRESS (block + blocks) );
+ result = ptr;
+ }
+ else if (blocks == heap->heapinfo[block].busy.info.size)
+ /* No size change necessary. */
+ result = ptr;
+ else {
+ /* Won't fit, so allocate a new region that will.
+ Free the old region first in case there is sufficient
+ adjacent free space to grow without moving. */
+ blocks = heap->heapinfo[block].busy.info.size;
+ /* Prevent free from actually returning memory to the system. */
+ oldlimit = heap->heaplimit;
+ heap->heaplimit = 0;
+ _fusion_shfree( heap, ptr );
+ heap->heaplimit = oldlimit;
+ result = _fusion_shmalloc( heap, size );
+ if (result == NULL) {
+ /* Now we're really in trouble. We have to unfree
+ the thing we just freed. Unfortunately it might
+ have been coalesced with its neighbors. */
+ if (heap->heapindex == block)
+ (void) _fusion_shmalloc( heap, blocks * BLOCKSIZE );
+ else {
+ void *previous = _fusion_shmalloc( heap, (block - heap->heapindex) * BLOCKSIZE );
+ (void) _fusion_shmalloc( heap, blocks * BLOCKSIZE );
+ _fusion_shfree( heap, previous );
+ }
+ return NULL;
+ }
+ if (ptr != result)
+ direct_memmove (result, ptr, blocks * BLOCKSIZE);
+ }
+ break;
+
+ default:
+ /* Old size is a fragment; type is logarithm
+ to base two of the fragment size. */
+ if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type))
+ /* The new size is the same kind of fragment. */
+ result = ptr;
+ else {
+ /* The new size is different; allocate a new space,
+ and copy the lesser of the new size and the old. */
+ result = _fusion_shmalloc( heap, size );
+ if (result == NULL)
+ return NULL;
+ direct_memcpy (result, ptr, MIN (size, (size_t) 1 << type));
+ _fusion_shfree( heap, ptr );
+ }
+ break;
+ }
+
+ return result;
+}
+
+/* Return memory to the heap. */
+void
+_fusion_shfree( shmalloc_heap *heap, void *ptr )
+{
+ int type;
+ size_t block, blocks;
+ register size_t i;
+ struct list *prev, *next;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %p )\n", __FUNCTION__, heap, ptr );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ if (ptr == NULL)
+ return;
+
+ block = BLOCK (ptr);
+
+ type = heap->heapinfo[block].busy.type;
+ switch (type) {
+ case 0:
+ /* Get as many statistics as early as we can. */
+ heap->chunks_used--;
+ heap->bytes_used -= heap->heapinfo[block].busy.info.size * BLOCKSIZE;
+ heap->bytes_free += heap->heapinfo[block].busy.info.size * BLOCKSIZE;
+
+ /* Find the free cluster previous to this one in the free list.
+ Start searching at the last block referenced; this may benefit
+ programs with locality of allocation. */
+ i = heap->heapindex;
+ if (i > block)
+ while (i > block)
+ i = heap->heapinfo[i].free.prev;
+ else {
+ do
+ i = heap->heapinfo[i].free.next;
+ while (i > 0 && i < block);
+ i = heap->heapinfo[i].free.prev;
+ }
+
+ /* Determine how to link this block into the free list. */
+ if (block == i + heap->heapinfo[i].free.size) {
+ /* Coalesce this block with its predecessor. */
+ heap->heapinfo[i].free.size += heap->heapinfo[block].busy.info.size;
+ block = i;
+ }
+ else {
+ /* Really link this block back into the free list. */
+ heap->heapinfo[block].free.size = heap->heapinfo[block].busy.info.size;
+ heap->heapinfo[block].free.next = heap->heapinfo[i].free.next;
+ heap->heapinfo[block].free.prev = i;
+ heap->heapinfo[i].free.next = block;
+ heap->heapinfo[heap->heapinfo[block].free.next].free.prev = block;
+ heap->chunks_free++;
+ }
+
+ /* Now that the block is linked in, see if we can coalesce it
+ with its successor (by deleting its successor from the list
+ and adding in its size). */
+ if (block + heap->heapinfo[block].free.size == heap->heapinfo[block].free.next) {
+ heap->heapinfo[block].free.size
+ += heap->heapinfo[heap->heapinfo[block].free.next].free.size;
+ heap->heapinfo[block].free.next
+ = heap->heapinfo[heap->heapinfo[block].free.next].free.next;
+ heap->heapinfo[heap->heapinfo[block].free.next].free.prev = block;
+ heap->chunks_free--;
+ }
+
+ blocks = heap->heapinfo[block].free.size;
+
+/* FIXME: as this is used when kernel is detected as >= 2.6.19.2 only, this fallback definition should be ok for now */
+#ifndef MADV_REMOVE
+#define MADV_REMOVE 9
+#endif
+ /* Punch a hole into the tmpfs file to really free RAM. */
+ if (fusion_config->madv_remove)
+ madvise( ADDRESS(block), blocks * BLOCKSIZE, MADV_REMOVE );
+
+ /* Now see if we can truncate the end. */
+ if (blocks >= FINAL_FREE_BLOCKS && block + blocks == heap->heaplimit
+ && __shmalloc_brk( heap, 0 ) == ADDRESS (block + blocks))
+ {
+ register size_t bytes = blocks * BLOCKSIZE;
+ heap->heaplimit -= blocks;
+ __shmalloc_brk( heap, -bytes );
+ heap->heapinfo[heap->heapinfo[block].free.prev].free.next = heap->heapinfo[block].free.next;
+ heap->heapinfo[heap->heapinfo[block].free.next].free.prev = heap->heapinfo[block].free.prev;
+ block = heap->heapinfo[block].free.prev;
+ heap->chunks_free--;
+ heap->bytes_free -= bytes;
+ }
+
+ /* Set the next search to begin at this block. */
+ heap->heapindex = block;
+ break;
+
+ default:
+ /* Do some of the statistics. */
+ heap->chunks_used--;
+ heap->bytes_used -= 1 << type;
+ heap->chunks_free++;
+ heap->bytes_free += 1 << type;
+
+ /* Get the address of the first free fragment in this block. */
+ prev = (struct list *) ((char *) ADDRESS (block) +
+ (heap->heapinfo[block].busy.info.frag.first << type));
+
+#if 1 /* Adapted from Mike */
+ if ((int)heap->heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1
+ && heap->fragblocks[type] > 1)
+#else
+ if ((int)heap->heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
+#endif
+ {
+ /* If all fragments of this block are free, remove them
+ from the fragment list and free the whole block. */
+#if 1 /* Adapted from Mike */
+ heap->fragblocks[type]--;
+#endif
+ next = prev;
+ for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
+ next = next->next;
+ prev->prev->next = next;
+ if (next != NULL)
+ next->prev = prev->prev;
+ heap->heapinfo[block].busy.type = 0;
+ heap->heapinfo[block].busy.info.size = 1;
+
+ /* Keep the statistics accurate. */
+ heap->chunks_used++;
+ heap->bytes_used += BLOCKSIZE;
+ heap->chunks_free -= BLOCKSIZE >> type;
+ heap->bytes_free -= BLOCKSIZE;
+
+ _fusion_shfree( heap, ADDRESS (block) );
+ }
+ else if (heap->heapinfo[block].busy.info.frag.nfree != 0) {
+ /* If some fragments of this block are free, link this
+ fragment into the fragment list after the first free
+ fragment of this block. */
+ next = (struct list *) ptr;
+ next->next = prev->next;
+ next->prev = prev;
+ prev->next = next;
+ if (next->next != NULL)
+ next->next->prev = next;
+ heap->heapinfo[block].busy.info.frag.nfree++;
+ }
+ else {
+ /* No fragments of this block are free, so link this
+ fragment into the fragment list and announce that
+ it is the first free fragment of this block. */
+ prev = (struct list *) ptr;
+ heap->heapinfo[block].busy.info.frag.nfree = 1;
+ heap->heapinfo[block].busy.info.frag.first = (unsigned long int)
+ ((unsigned long int) ((char *) ptr - (char *) NULL)
+ % BLOCKSIZE >> type);
+ prev->next = heap->fraghead[type].next;
+ prev->prev = &heap->fraghead[type];
+ prev->prev->next = prev;
+ if (prev->next != NULL)
+ prev->next->prev = prev;
+ }
+ break;
+ }
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+__shmalloc_init_heap( FusionSHM *shm,
+ const char *filename,
+ void *addr_base,
+ int space,
+ int *ret_fd,
+ int *ret_size )
+{
+ DirectResult ret;
+ int size;
+ FusionSHMShared *shared;
+ int heapsize = (space + BLOCKSIZE-1) / BLOCKSIZE;
+ int fd = -1;
+ shmalloc_heap *heap = NULL;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, '%s', %p, %d, %p, %p )\n",
+ __FUNCTION__, shm, filename, addr_base, space, ret_fd, ret_size );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_ASSERT( filename != NULL );
+ D_ASSERT( addr_base != NULL );
+ D_ASSERT( ret_fd != NULL );
+ D_ASSERT( ret_size != NULL );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+ D_ASSERT( shared->tmpfs[0] != 0 );
+
+ size = BLOCKALIGN(sizeof(shmalloc_heap)) + BLOCKALIGN( heapsize * sizeof(shmalloc_info) );
+
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> opening shared memory file '%s'...\n", filename );
+
+ /* open the virtual file */
+ fd = open( filename, O_RDWR | O_CREAT | O_TRUNC, 0660 );
+ if (fd < 0) {
+ ret = errno2result(errno);
+ D_PERROR( "Fusion/SHM: Could not open shared memory file '%s'!\n", filename );
+ goto error;
+ }
+
+ if (fusion_config->shmfile_gid != (gid_t)-1) {
+ /* chgrp the SH_FILE dev entry */
+ if (fchown( fd, -1, fusion_config->shmfile_gid ) != 0)
+ D_WARN( "Fusion/SHM: Changing owner on %s failed... continuing on.", filename );
+ }
+
+ fchmod( fd, 0660 );
+ ftruncate( fd, size );
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> mmaping shared memory file... (%d bytes)\n", size );
+
+ /* map it shared */
+ heap = mmap( addr_base, size + space, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0 );
+ if (heap == MAP_FAILED) {
+ ret = errno2result(errno);
+ D_PERROR( "Fusion/SHM: Could not mmap shared memory file '%s'!\n", filename );
+ goto error;
+ }
+
+ if (heap != addr_base) {
+ D_ERROR( "Fusion/SHM: mmap() returned address (%p) differs from requested (%p)\n", heap, addr_base );
+ ret = DR_FUSION;
+ goto error;
+ }
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> done.\n" );
+
+ heap->size = size;
+ heap->heapsize = heapsize;
+ heap->heapinfo = (void*) heap + BLOCKALIGN(sizeof(shmalloc_heap));
+ heap->heapbase = (char*) heap->heapinfo;
+
+ D_MAGIC_SET( heap, shmalloc_heap );
+
+ *ret_fd = fd;
+ *ret_size = size;
+
+ return DR_OK;
+
+
+error:
+ if (heap)
+ munmap( heap, size );
+
+ if (fd != -1) {
+ close( fd );
+ unlink( filename );
+ }
+
+ return ret;
+}
+
+DirectResult
+__shmalloc_join_heap( FusionSHM *shm,
+ const char *filename,
+ void *addr_base,
+ int size,
+ int *ret_fd )
+{
+ DirectResult ret;
+ FusionSHMShared *shared;
+ int fd = -1;
+ shmalloc_heap *heap = NULL;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, '%s', %p, %d, %p )\n",
+ __FUNCTION__, shm, filename, addr_base, size, ret_fd );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_ASSERT( filename != NULL );
+ D_ASSERT( addr_base != NULL );
+ D_ASSERT( size >= sizeof(shmalloc_heap) );
+ D_ASSERT( ret_fd != NULL );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+ D_ASSERT( shared->tmpfs[0] != 0 );
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> opening shared memory file '%s'...\n", filename );
+
+ /* open the virtual file */
+ fd = open( filename, O_RDWR );
+ if (fd < 0) {
+ ret = errno2result(errno);
+ D_PERROR( "Fusion/SHM: Could not open shared memory file '%s'!\n", filename );
+ goto error;
+ }
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> mmaping shared memory file... (%d bytes)\n", size );
+
+ /* map it shared */
+ heap = mmap( addr_base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0 );
+ if (heap == MAP_FAILED) {
+ ret = errno2result(errno);
+ D_PERROR( "Fusion/SHM: Could not mmap shared memory file '%s'!\n", filename );
+ goto error;
+ }
+
+ if (heap != addr_base) {
+ D_ERROR( "Fusion/SHM: mmap() returned address (%p) differs from requested (%p)\n", heap, addr_base );
+ ret = DR_FUSION;
+ goto error;
+ }
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ D_DEBUG_AT( Fusion_SHMHeap, " -> done.\n" );
+
+ *ret_fd = fd;
+
+ return DR_OK;
+
+
+error:
+ if (heap)
+ munmap( heap, size );
+
+ if (fd != -1)
+ close( fd );
+
+ return ret;
+}
+
+void *
+__shmalloc_brk( shmalloc_heap *heap, int increment )
+{
+ FusionSHMShared *shm;
+ FusionWorld *world;
+ FusionSHMPool *pool;
+ FusionSHMPoolShared *shared;
+
+ D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %d )\n", __FUNCTION__, heap, increment );
+
+ D_MAGIC_ASSERT( heap, shmalloc_heap );
+
+ shared = heap->pool;
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+ shm = shared->shm;
+ D_MAGIC_ASSERT( shm, FusionSHMShared );
+
+ world = _fusion_world( shm->world );
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ pool = &world->shm.pools[shared->index];
+ D_MAGIC_ASSERT( pool, FusionSHMPool );
+
+ if (increment) {
+ int new_size = heap->size + increment;
+
+ if (new_size > shared->max_size) {
+ D_WARN( "maximum shared memory size exceeded!" );
+ fusion_dbg_print_memleaks( shared );
+ return NULL;
+ }
+
+ if (ftruncate( pool->fd, new_size ) < 0) {
+ D_PERROR( "Fusion/SHM: ftruncating shared memory file failed!\n" );
+ return NULL;
+ }
+
+ heap->size = new_size;
+ }
+
+ return shared->addr_base + heap->size - increment;
+}
+
diff --git a/Source/DirectFB/lib/fusion/shm/pool.c b/Source/DirectFB/lib/fusion/shm/pool.c
new file mode 100755
index 0000000..030314f
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/pool.c
@@ -0,0 +1,954 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/mem.h>
+#include <direct/messages.h>
+
+#include <fusion/shmalloc.h>
+#include <fusion/fusion_internal.h>
+
+#include <fusion/shm/pool.h>
+#include <fusion/shm/shm_internal.h>
+
+
+D_DEBUG_DOMAIN( Fusion_SHMPool, "Fusion/SHMPool", "Fusion Shared Memory Pool" );
+
+/**********************************************************************************************************************/
+
+static DirectResult init_pool ( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared,
+ const char *name,
+ unsigned int max_size,
+ bool debug );
+
+static DirectResult join_pool ( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared );
+
+static void leave_pool ( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared );
+
+static void shutdown_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared );
+
+/**********************************************************************************************************************/
+
+DirectResult
+fusion_shm_pool_create( FusionWorld *world,
+ const char *name,
+ unsigned int max_size,
+ bool debug,
+ FusionSHMPoolShared **ret_pool )
+{
+ int i;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+ D_MAGIC_ASSERT( world->shared, FusionWorldShared );
+ D_ASSERT( name != NULL );
+ D_ASSERT( max_size > 0 );
+ D_ASSERT( ret_pool != NULL );
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p [%d], '%s', %d, %p, %sdebug )\n", __FUNCTION__,
+ world, world->shared->world_index, name, max_size, ret_pool, debug ? "" : "non-" );
+
+#if !DIRECT_BUILD_DEBUGS
+ debug = false;
+#endif
+
+ shm = &world->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ if (max_size < 8192) {
+ D_ERROR( "Fusion/SHMPool: Maximum size (%d) should be 8192 at least!\n", max_size );
+ return DR_INVARG;
+ }
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ goto error;
+
+ if (shared->num_pools == FUSION_SHM_MAX_POOLS) {
+ D_ERROR( "Fusion/SHMPool: Maximum number of pools (%d) already reached!\n", FUSION_SHM_MAX_POOLS );
+ ret = DR_LIMITEXCEEDED;
+ goto error;
+ }
+
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (!shared->pools[i].active)
+ break;
+
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+ D_MAGIC_ASSUME( &shm->pools[i], FusionSHMPool );
+ }
+
+ D_ASSERT( i < FUSION_SHM_MAX_POOLS );
+
+ D_DEBUG_AT( Fusion_SHMPool, " -> index %d\n", i );
+
+ memset( &shm->pools[i], 0, sizeof(FusionSHMPool) );
+ memset( &shared->pools[i], 0, sizeof(FusionSHMPoolShared) );
+
+ shared->pools[i].index = i;
+
+ ret = init_pool( shm, &shm->pools[i], &shared->pools[i], name, max_size, debug );
+ if (ret)
+ goto error;
+
+ shared->num_pools++;
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ *ret_pool = &shared->pools[i];
+
+ D_DEBUG_AT( Fusion_SHMPool, " -> %p\n", *ret_pool );
+
+ return DR_OK;
+
+
+error:
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return ret;
+}
+
+DirectResult
+fusion_shm_pool_destroy( FusionWorld *world,
+ FusionSHMPoolShared *pool )
+{
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, world, pool );
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ shm = &world->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ D_ASSERT( shared == pool->shm );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return ret;
+
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return ret;
+ }
+
+ D_ASSERT( pool->active );
+ D_ASSERT( pool->index >= 0 );
+ D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS );
+ D_ASSERT( pool->pool_id == shm->pools[pool->index].pool_id );
+ D_ASSERT( pool == &shared->pools[pool->index] );
+
+ D_MAGIC_ASSERT( &shm->pools[pool->index], FusionSHMPool );
+
+ shutdown_pool( shm, &shm->pools[pool->index], pool );
+
+ shared->num_pools--;
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_attach( FusionSHM *shm,
+ FusionSHMPoolShared *pool )
+{
+ DirectResult ret;
+ FusionSHMShared *shared;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, shm, pool );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ D_ASSERT( shared == pool->shm );
+
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret) {
+ return ret;
+ }
+
+ D_ASSERT( pool->active );
+ D_ASSERT( pool->index >= 0 );
+ D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS );
+ D_ASSERT( pool == &shared->pools[pool->index] );
+ D_ASSERT( !shm->pools[pool->index].attached );
+
+ ret = join_pool( shm, &shm->pools[pool->index], pool );
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return ret;
+}
+
+DirectResult
+fusion_shm_pool_detach( FusionSHM *shm,
+ FusionSHMPoolShared *pool )
+{
+ DirectResult ret;
+ FusionSHMShared *shared;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, shm, pool );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ D_ASSERT( shared == pool->shm );
+
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret) {
+ fusion_skirmish_dismiss( &shared->lock );
+ return ret;
+ }
+
+ D_ASSERT( pool->active );
+ D_ASSERT( pool->index >= 0 );
+ D_ASSERT( pool->index < FUSION_SHM_MAX_POOLS );
+ D_ASSERT( pool->pool_id == shm->pools[pool->index].pool_id );
+ D_ASSERT( pool == &shared->pools[pool->index] );
+ D_ASSERT( shm->pools[pool->index].attached );
+
+ D_MAGIC_ASSERT( &shm->pools[pool->index], FusionSHMPool );
+
+ leave_pool( shm, &shm->pools[pool->index], pool );
+
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_allocate( FusionSHMPoolShared *pool,
+ int size,
+ bool clear,
+ bool lock,
+ void **ret_data )
+{
+ DirectResult ret;
+ void *data;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %d, %sclear, %p )\n", __FUNCTION__,
+ pool, size, clear ? "" : "un", ret_data );
+
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_ASSERT( size > 0 );
+ D_ASSERT( ret_data != NULL );
+
+ if (lock) {
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret)
+ return ret;
+ }
+
+ __shmalloc_brk( pool->heap, 0 );
+
+ data = _fusion_shmalloc( pool->heap, size );
+ if (!data) {
+ if (lock)
+ fusion_skirmish_dismiss( &pool->lock );
+ return DR_NOSHAREDMEMORY;
+ }
+
+ if (clear)
+ memset( data, 0, size );
+
+ *ret_data = data;
+
+ if (lock)
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_reallocate( FusionSHMPoolShared *pool,
+ void *data,
+ int size,
+ bool lock,
+ void **ret_data )
+{
+ DirectResult ret;
+ void *new_data;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %d, %p )\n",
+ __FUNCTION__, pool, data, size, ret_data );
+
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( data >= pool->addr_base );
+ D_ASSERT( data < pool->addr_base + pool->max_size );
+ D_ASSERT( size > 0 );
+ D_ASSERT( ret_data != NULL );
+
+ if (lock) {
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret)
+ return ret;
+ }
+
+ __shmalloc_brk( pool->heap, 0 );
+
+ new_data = _fusion_shrealloc( pool->heap, data, size );
+ if (!new_data) {
+ if (lock)
+ fusion_skirmish_dismiss( &pool->lock );
+ return DR_NOSHAREDMEMORY;
+ }
+
+ *ret_data = new_data;
+
+ if (lock)
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_pool_deallocate( FusionSHMPoolShared *pool,
+ void *data,
+ bool lock )
+{
+ DirectResult ret;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, pool, data );
+
+ D_MAGIC_ASSERT( pool, FusionSHMPoolShared );
+
+ D_ASSERT( data != NULL );
+ D_ASSERT( data >= pool->addr_base );
+ D_ASSERT( data < pool->addr_base + pool->max_size );
+
+ if (lock) {
+ ret = fusion_skirmish_prevail( &pool->lock );
+ if (ret)
+ return ret;
+ }
+
+ __shmalloc_brk( pool->heap, 0 );
+
+ _fusion_shfree( pool->heap, data );
+
+ if (lock)
+ fusion_skirmish_dismiss( &pool->lock );
+
+ return DR_OK;
+}
+
+/**********************************************************************************************************************/
+
+#if FUSION_BUILD_KERNEL
+
+static DirectResult
+init_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared,
+ const char *name,
+ unsigned int max_size,
+ bool debug )
+{
+ DirectResult ret;
+ int fd;
+ int size;
+ FusionWorld *world;
+ FusionSHMPoolNew pool_new = { .pool_id = 0 };
+ FusionSHMPoolAttach pool_attach = { .pool_id = 0 };
+ FusionEntryInfo info;
+ char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n",
+ __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
+ D_ASSERT( name != NULL );
+ D_ASSERT( max_size > sizeof(shmalloc_heap) );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ D_ASSERT( pool != NULL );
+ D_ASSERT( shared != NULL );
+
+ /* Fill out information for new pool. */
+ pool_new.max_size = max_size;
+
+ pool_new.max_size += BLOCKALIGN(sizeof(shmalloc_heap)) +
+ BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) );
+
+ /* Create the new pool. */
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_NEW, &pool_new )) {
+ if (errno == EINTR)
+ continue;
+
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_NEW failed!\n" );
+ return DR_FUSION;
+ }
+
+ /* Set the pool info. */
+ info.type = FT_SHMPOOL;
+ info.id = pool_new.pool_id;
+
+ snprintf( info.name, sizeof(info.name), "%s", name );
+
+ ioctl( world->fusion_fd, FUSION_ENTRY_SET_INFO, &info );
+
+
+ /* Set pool to attach to. */
+ pool_attach.pool_id = pool_new.pool_id;
+
+ /* Attach to the pool. */
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
+ if (errno == EINTR)
+ continue;
+
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );
+
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
+ if (errno != EINTR) {
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
+ break;
+ }
+ }
+
+ return DR_FUSION;
+ }
+
+
+ /* Generate filename. */
+ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
+ fusion_world_index( shm->world ), pool_new.pool_id );
+
+ /* Initialize the heap. */
+ ret = __shmalloc_init_heap( shm, buf, pool_new.addr_base, max_size, &fd, &size );
+ if (ret) {
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
+ if (errno != EINTR) {
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+
+ /* Initialize local data. */
+ pool->attached = true;
+ pool->shm = shm;
+ pool->shared = shared;
+ pool->pool_id = pool_new.pool_id;
+ pool->fd = fd;
+ pool->filename = D_STRDUP( buf );
+
+ /* Initialize shared data. */
+ shared->active = true;
+ shared->debug = debug;
+ shared->shm = shm->shared;
+ shared->max_size = pool_new.max_size;
+ shared->pool_id = pool_new.pool_id;
+ shared->addr_base = pool_new.addr_base;
+ shared->heap = pool_new.addr_base;
+ shared->heap->pool = shared;
+
+ fusion_skirmish_init( &shared->lock, name, world );
+
+
+ D_MAGIC_SET( pool, FusionSHMPool );
+ D_MAGIC_SET( shared, FusionSHMPoolShared );
+
+
+ shared->name = SHSTRDUP( shared, name );
+
+ return DR_OK;
+}
+
+static DirectResult
+join_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ DirectResult ret;
+ int fd;
+ FusionWorld *world;
+ FusionSHMPoolAttach pool_attach = { .pool_id = 0 };
+ char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+#if !DIRECT_BUILD_DEBUGS
+ if (shared->debug) {
+ D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" );
+ return DR_UNSUPPORTED;
+ }
+#endif
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+
+ /* Set pool to attach to. */
+ pool_attach.pool_id = shared->pool_id;
+
+ /* Attach to the pool. */
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
+ if (errno == EINTR)
+ continue;
+
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );
+ return DR_FUSION;
+ }
+
+
+ /* Generate filename. */
+ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
+ fusion_world_index( shm->world ), shared->pool_id );
+
+ /* Join the heap. */
+ ret = __shmalloc_join_heap( shm, buf, pool_attach.addr_base, shared->max_size, &fd );
+ if (ret) {
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
+ if (errno != EINTR) {
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+
+ /* Initialize local data. */
+ pool->attached = true;
+ pool->shm = shm;
+ pool->shared = shared;
+ pool->pool_id = shared->pool_id;
+ pool->fd = fd;
+ pool->filename = D_STRDUP( buf );
+
+
+ D_MAGIC_SET( pool, FusionSHMPool );
+
+ return DR_OK;
+}
+
+static void
+leave_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ FusionWorld *world;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPool );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
+ if (errno != EINTR) {
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
+ break;
+ }
+ }
+
+ if (munmap( shared->addr_base, shared->max_size ))
+ D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );
+
+ if (pool->fd != -1 && close( pool->fd ))
+ D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );
+
+ pool->attached = false;
+
+ D_FREE( pool->filename );
+
+ D_MAGIC_CLEAR( pool );
+}
+
+static void
+shutdown_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ FusionWorld *world;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPool );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ SHFREE( shared, shared->name );
+
+ fusion_dbg_print_memleaks( shared );
+
+ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
+ if (errno != EINTR) {
+ D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
+ break;
+ }
+ }
+
+ if (munmap( shared->addr_base, shared->max_size ))
+ D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );
+
+ if (pool->fd != -1 && close( pool->fd ))
+ D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );
+
+ if (unlink( pool->filename ))
+ D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename );
+
+ shared->active = false;
+
+ pool->attached = false;
+
+ D_FREE( pool->filename );
+
+ D_MAGIC_CLEAR( pool );
+
+ fusion_skirmish_destroy( &shared->lock );
+
+ D_MAGIC_CLEAR( shared );
+}
+
+#else /* FUSION_BUILD_KERNEL */
+
+static DirectResult
+init_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared,
+ const char *name,
+ unsigned int max_size,
+ bool debug )
+{
+ DirectResult ret;
+ int fd;
+ int size;
+ long page_size;
+ int pool_id;
+ unsigned int pool_max_size;
+ void *pool_addr_base = NULL;
+ FusionWorld *world;
+ char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n",
+ __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
+ D_ASSERT( name != NULL );
+ D_ASSERT( max_size > sizeof(shmalloc_heap) );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ D_ASSERT( pool != NULL );
+ D_ASSERT( shared != NULL );
+
+ page_size = direct_pagesize();
+
+ pool_id = ++world->shared->pool_ids;
+
+ pool_max_size = max_size + BLOCKALIGN(sizeof(shmalloc_heap)) +
+ BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) );
+
+ pool_addr_base = world->shared->pool_base;
+ world->shared->pool_base += ((pool_max_size + page_size - 1) & ~(page_size - 1)) + page_size;
+ /* Exceeded limit? */
+ if (world->shared->pool_base > world->shared->pool_max)
+ return DR_NOSHAREDMEMORY;
+
+ /* Generate filename. */
+ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
+ fusion_world_index( world ), pool_id );
+
+ /* Initialize the heap. */
+ ret = __shmalloc_init_heap( shm, buf, pool_addr_base, max_size, &fd, &size );
+ if (ret)
+ return ret;
+
+ /* Initialize local data. */
+ pool->attached = true;
+ pool->shm = shm;
+ pool->shared = shared;
+ pool->pool_id = pool_id;
+ pool->fd = fd;
+ pool->filename = D_STRDUP( buf );
+
+ /* Initialize shared data. */
+ shared->active = true;
+ shared->debug = debug;
+ shared->shm = shm->shared;
+ shared->max_size = pool_max_size;
+ shared->pool_id = pool_id;
+ shared->addr_base = pool_addr_base;
+ shared->heap = pool_addr_base;
+ shared->heap->pool = shared;
+
+ fusion_skirmish_init( &shared->lock, name, world );
+
+
+ D_MAGIC_SET( pool, FusionSHMPool );
+ D_MAGIC_SET( shared, FusionSHMPoolShared );
+
+
+ shared->name = SHSTRDUP( shared, name );
+
+ return DR_OK;
+}
+
+static DirectResult
+join_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ DirectResult ret;
+ int fd;
+ FusionWorld *world;
+ char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+#if !DIRECT_BUILD_DEBUGS
+ if (shared->debug) {
+ D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" );
+ return DR_UNSUPPORTED;
+ }
+#endif
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ /* Generate filename. */
+ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
+ fusion_world_index( shm->world ), shared->pool_id );
+
+ /* Join the heap. */
+ ret = __shmalloc_join_heap( shm, buf, shared->addr_base, shared->max_size, &fd );
+ if (ret)
+ return ret;
+
+ /* Initialize local data. */
+ pool->attached = true;
+ pool->shm = shm;
+ pool->shared = shared;
+ pool->pool_id = shared->pool_id;
+ pool->fd = fd;
+ pool->filename = D_STRDUP( buf );
+
+
+ D_MAGIC_SET( pool, FusionSHMPool );
+
+ return DR_OK;
+}
+
+static void
+leave_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ FusionWorld *world;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPool );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ if (munmap( shared->addr_base, shared->max_size ))
+ D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );
+
+ if (pool->fd != -1 && close( pool->fd ))
+ D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );
+
+ pool->attached = false;
+
+ D_FREE( pool->filename );
+
+ D_MAGIC_CLEAR( pool );
+}
+
+static void
+shutdown_pool( FusionSHM *shm,
+ FusionSHMPool *pool,
+ FusionSHMPoolShared *shared )
+{
+ FusionWorld *world;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( pool, FusionSHMPool );
+ D_MAGIC_ASSERT( shared, FusionSHMPoolShared );
+
+ world = shm->world;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ SHFREE( shared, shared->name );
+
+ fusion_dbg_print_memleaks( shared );
+
+ if (munmap( shared->addr_base, shared->max_size ))
+ D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );
+
+ if (pool->fd != -1 && close( pool->fd ))
+ D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );
+
+ if (unlink( pool->filename ))
+ D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename );
+
+ shared->active = false;
+
+ pool->attached = false;
+
+ D_FREE( pool->filename );
+
+ D_MAGIC_CLEAR( pool );
+
+ fusion_skirmish_destroy( &shared->lock );
+
+ D_MAGIC_CLEAR( shared );
+}
+
+#endif /* FUSION_BUILD_KERNEL */
+
+/**********************************************************************************************************************/
+
+#if FUSION_BUILD_KERNEL
+void
+_fusion_shmpool_process( FusionWorld *world,
+ int pool_id,
+ FusionSHMPoolMessage *msg )
+{
+ int i;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %d, %p )\n", __FUNCTION__, world, pool_id, msg );
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ shm = &world->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return;
+
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (shm->pools[i].attached) {
+ D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool );
+
+ if (shm->pools[i].pool_id == pool_id) {
+ switch (msg->type) {
+ case FSMT_REMAP:
+ break;
+
+ case FSMT_UNMAP:
+ D_UNIMPLEMENTED();
+ break;
+ }
+
+ break;
+ }
+ }
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+}
+#endif /* FUSION_BUILD_KERNEL */
diff --git a/Source/DirectFB/lib/fusion/shm/pool.h b/Source/DirectFB/lib/fusion/shm/pool.h
new file mode 100755
index 0000000..b809a5a
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/pool.h
@@ -0,0 +1,69 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __FUSION__SHM__POOL_H__
+#define __FUSION__SHM__POOL_H__
+
+#include <fusion/types.h>
+
+
+DirectResult fusion_shm_pool_create ( FusionWorld *world,
+ const char *name,
+ unsigned int max_size,
+ bool debug,
+ FusionSHMPoolShared **ret_pool );
+
+DirectResult fusion_shm_pool_destroy ( FusionWorld *world,
+ FusionSHMPoolShared *pool );
+
+
+DirectResult fusion_shm_pool_attach ( FusionSHM *shm,
+ FusionSHMPoolShared *pool );
+
+DirectResult fusion_shm_pool_detach ( FusionSHM *shm,
+ FusionSHMPoolShared *pool );
+
+
+DirectResult fusion_shm_pool_allocate ( FusionSHMPoolShared *pool,
+ int size,
+ bool clear,
+ bool lock,
+ void **ret_data );
+
+DirectResult fusion_shm_pool_reallocate( FusionSHMPoolShared *pool,
+ void *data,
+ int size,
+ bool lock,
+ void **ret_data );
+
+DirectResult fusion_shm_pool_deallocate( FusionSHMPoolShared *pool,
+ void *data,
+ bool lock );
+
+#endif
+
diff --git a/Source/DirectFB/lib/fusion/shm/shm.c b/Source/DirectFB/lib/fusion/shm/shm.c
new file mode 100755
index 0000000..21c7f42
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/shm.c
@@ -0,0 +1,337 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+
+#include <direct/debug.h>
+#include <direct/list.h>
+#include <direct/signals.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <fusion/conf.h>
+#include <fusion/fusion_internal.h>
+
+#include <fusion/shm/pool.h>
+#include <fusion/shm/shm.h>
+#include <fusion/shm/shm_internal.h>
+
+
+/**********************************************************************************************************************/
+
+static int
+find_tmpfs( char *name, int len )
+{
+ int largest = 0;
+ char buffer[1024];
+ FILE *mounts_handle;
+
+ mounts_handle = fopen( "/proc/mounts", "r" );
+ if (!mounts_handle)
+ return 0;
+
+ while (fgets( buffer, sizeof(buffer), mounts_handle )) {
+ char *mount_point;
+ char *mount_fs;
+ char *pointer = buffer;
+
+ strsep( &pointer, " " );
+
+ mount_point = strsep( &pointer, " " );
+ mount_fs = strsep( &pointer, " " );
+
+ if (mount_fs && mount_point && !access( mount_point, W_OK ) &&
+ (!strcmp( mount_fs, "tmpfs" ) || !strcmp( mount_fs, "shmfs" ) || !strcmp( mount_fs, "ramfs" )))
+ {
+ struct statfs stat;
+ int bytes;
+
+ if (statfs( mount_point, &stat )) {
+ D_PERROR( "Fusion/SHM: statfs on '%s' failed!\n", mount_point );
+ continue;
+ }
+
+ bytes = stat.f_blocks * stat.f_bsize;
+
+ if (bytes > largest || (bytes == largest && !strcmp(mount_point,"/dev/shm"))) {
+ largest = bytes;
+
+ direct_snputs( name, mount_point, len );
+ }
+ }
+ }
+
+ fclose( mounts_handle );
+
+ return largest;
+}
+
+/**********************************************************************************************************************/
+
+DirectResult
+fusion_shm_init( FusionWorld *world )
+{
+ int i;
+ int num;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+ D_MAGIC_ASSERT( world->shared, FusionWorldShared );
+
+ shm = &world->shm;
+ shared = &world->shared->shm;
+
+ /* Initialize local data. */
+ memset( shm, 0, sizeof(FusionSHM) );
+
+ shm->world = world;
+ shm->shared = shared;
+
+ /* Initialize shared data. */
+ if (fusion_master( world )) {
+ memset( shared, 0, sizeof(FusionSHMShared) );
+
+ if (fusion_config->tmpfs) {
+ snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, fusion_config->tmpfs );
+ }
+ else if (!find_tmpfs( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN )) {
+ D_ERROR( "Fusion/SHM: Could not find tmpfs mount point, falling back to /dev/shm!\n" );
+ snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, "/dev/shm" );
+ }
+
+ shared->world = world->shared;
+
+ /* Initialize shared lock. */
+ ret = fusion_skirmish_init( &shared->lock, "Fusion SHM", world );
+ if (ret) {
+ D_DERROR( ret, "Fusion/SHM: Failed to create skirmish!\n" );
+ return ret;
+ }
+
+ /* Initialize static pool array. */
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++)
+ shared->pools[i].index = i;
+
+ D_MAGIC_SET( shm, FusionSHM );
+ D_MAGIC_SET( shared, FusionSHMShared );
+ }
+ else {
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return ret;
+
+ D_MAGIC_SET( shm, FusionSHM );
+
+ for (i=0, num=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (shared->pools[i].active) {
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+
+ ret = fusion_shm_pool_attach( shm, &shared->pools[i] );
+ if (ret) {
+ for (--i; i>=0; i--) {
+ if (shared->pools[i].active)
+ fusion_shm_pool_detach( shm, &shared->pools[i] );
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ D_MAGIC_CLEAR( shm );
+
+ return ret;
+ }
+
+ num++;
+ }
+ }
+
+ D_ASSERT( num == shared->num_pools );
+
+ fusion_skirmish_dismiss( &shared->lock );
+ }
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_deinit( FusionWorld *world )
+{
+ int i;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+
+ shm = &world->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+
+ shared = shm->shared;
+
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return ret;
+
+ /* Deinitialize shared data. */
+ if (fusion_master( world )) {
+ D_ASSUME( shared->num_pools == 0 );
+
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (shared->pools[i].active) {
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+ D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool );
+
+ D_WARN( "destroying remaining '%s'", shared->pools[i].name );
+
+ fusion_shm_pool_destroy( world, &shared->pools[i] );
+ }
+ }
+
+ /* Destroy shared lock. */
+ fusion_skirmish_destroy( &shared->lock );
+
+ D_MAGIC_CLEAR( shared );
+ }
+ else {
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (shared->pools[i].active) {
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+ D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool );
+
+ fusion_shm_pool_detach( shm, &shared->pools[i] );
+ }
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+ }
+
+ D_MAGIC_CLEAR( shm );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_attach_unattached( FusionWorld *world )
+{
+ int i;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+ D_MAGIC_ASSERT( world->shared, FusionWorldShared );
+
+ shm = &world->shm;
+ shared = &world->shared->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return ret;
+
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (!shared->pools[i].active)
+ continue;
+
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+
+ if (!shm->pools[i].attached) {
+ ret = fusion_shm_pool_attach( shm, &shared->pools[i] );
+ if (ret)
+ D_DERROR( ret, "fusion_shm_pool_attach( '%s' ) failed!\n", shared->pools[i].name );
+ }
+ else
+ D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool );
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DR_OK;
+}
+
+DirectResult
+fusion_shm_enum_pools( FusionWorld *world,
+ FusionSHMPoolCallback callback,
+ void *ctx )
+{
+ int i;
+ DirectResult ret;
+ FusionSHM *shm;
+ FusionSHMShared *shared;
+
+ D_MAGIC_ASSERT( world, FusionWorld );
+ D_MAGIC_ASSERT( world->shared, FusionWorldShared );
+ D_ASSERT( callback != NULL );
+
+ shm = &world->shm;
+ shared = &world->shared->shm;
+
+ D_MAGIC_ASSERT( shm, FusionSHM );
+ D_MAGIC_ASSERT( shared, FusionSHMShared );
+
+ ret = fusion_skirmish_prevail( &shared->lock );
+ if (ret)
+ return ret;
+
+ for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
+ if (!shared->pools[i].active)
+ continue;
+
+ if (!shm->pools[i].attached) {
+ D_BUG( "not attached to pool" );
+ continue;
+ }
+
+ D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool );
+ D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
+
+ if (callback( &shm->pools[i], ctx ) == DENUM_CANCEL)
+ break;
+ }
+
+ fusion_skirmish_dismiss( &shared->lock );
+
+ return DR_OK;
+}
+
diff --git a/Source/DirectFB/lib/fusion/shm/shm.h b/Source/DirectFB/lib/fusion/shm/shm.h
new file mode 100755
index 0000000..6764d17
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/shm.h
@@ -0,0 +1,48 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __FUSION__SHM__SHM_H__
+#define __FUSION__SHM__SHM_H__
+
+#include <fusion/types.h>
+
+typedef DirectEnumerationResult (*FusionSHMPoolCallback)( FusionSHMPool *pool,
+ void *ctx );
+
+DirectResult fusion_shm_init ( FusionWorld *world );
+
+DirectResult fusion_shm_deinit( FusionWorld *world );
+
+DirectResult fusion_shm_attach_unattached( FusionWorld *world );
+
+DirectResult fusion_shm_enum_pools( FusionWorld *world,
+ FusionSHMPoolCallback callback,
+ void *ctx );
+
+#endif
+
diff --git a/Source/DirectFB/lib/fusion/shm/shm_internal.h b/Source/DirectFB/lib/fusion/shm/shm_internal.h
new file mode 100755
index 0000000..3e282a5
--- /dev/null
+++ b/Source/DirectFB/lib/fusion/shm/shm_internal.h
@@ -0,0 +1,264 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __FUSION__SHM__SHM_INTERNAL_H__
+#define __FUSION__SHM__SHM_INTERNAL_H__
+
+#include <limits.h>
+
+#include <direct/list.h>
+
+#include <fusion/build.h>
+#include <fusion/lock.h>
+
+
+#define FUSION_SHM_MAX_POOLS 24
+#define FUSION_SHM_TMPFS_PATH_NAME_LEN 64
+
+
+typedef struct __shmalloc_heap shmalloc_heap;
+
+
+/*
+ * Local pool data.
+ */
+struct __Fusion_FusionSHMPool {
+ int magic;
+
+ bool attached; /* Indicates usage of this entry in the static pool array. */
+
+ FusionSHM *shm; /* Back pointer to local SHM data. */
+
+ FusionSHMPoolShared *shared; /* Pointer to shared pool data. */
+
+ int pool_id; /* The pool's ID within the world. */
+
+ int fd; /* File descriptor of shared memory file. */
+ char *filename; /* Name of the shared memory file. */
+};
+
+/*
+ * Shared pool data.
+ */
+struct __Fusion_FusionSHMPoolShared {
+ int magic;
+
+ bool debug; /* Debug allocations in this pool? */
+
+ int index; /* Index within the static pool array. */
+ bool active; /* Indicates usage of this entry in the static pool array. */
+
+ FusionSHMShared *shm; /* Back pointer to shared SHM data. */
+
+ int max_size; /* Maximum possible size of the shared memory. */
+ int pool_id; /* The pool's ID within the world. */
+ void *addr_base; /* Virtual starting address of shared memory. */
+
+ FusionSkirmish lock; /* Lock for this pool. */
+
+ shmalloc_heap *heap; /* The actual heap information ported from libc5. */
+
+ char *name; /* Name of the pool (allocated in the pool). */
+
+ DirectLink *allocs; /* Used for debugging. */
+};
+
+
+/*
+ * Local SHM data.
+ */
+struct __Fusion_FusionSHM {
+ int magic;
+
+ FusionWorld *world; /* Back pointer to local world data. */
+
+ FusionSHMShared *shared; /* Pointer to shared SHM data. */
+
+ FusionSHMPool pools[FUSION_SHM_MAX_POOLS]; /* Local data of all pools. */
+
+ DirectSignalHandler *signal_handler;
+};
+
+/*
+ * Shared SHM data.
+ */
+struct __Fusion_FusionSHMShared {
+ int magic;
+
+ FusionWorldShared *world; /* Back pointer to shared world data. */
+
+ FusionSkirmish lock; /* Lock for list of pools. */
+
+ int num_pools; /* Number of active pools. */
+ FusionSHMPoolShared pools[FUSION_SHM_MAX_POOLS]; /* Shared data of all pools. */
+
+ char tmpfs[FUSION_SHM_TMPFS_PATH_NAME_LEN];
+};
+
+
+
+/* The allocator divides the heap into blocks of fixed size; large
+ requests receive one or more whole blocks, and small requests
+ receive a fragment of a block. Fragment sizes are powers of two,
+ and all fragments of a block are the same size. When all the
+ fragments in a block have been freed, the block itself is freed. */
+#define INT_BIT (CHAR_BIT * sizeof(int))
+#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
+#define BLOCKSIZE (1 << BLOCKLOG)
+#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
+#define BLOCKALIGN(SIZE) (((SIZE) + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1))
+
+/* Number of contiguous free blocks allowed to build up at the end of
+ memory before they will be returned to the system. */
+#define FINAL_FREE_BLOCKS 8
+
+/* Address to block number and vice versa. */
+#define BLOCK(A) (((char *) (A) - heap->heapbase) / BLOCKSIZE + 1)
+#define ADDRESS(B) ((void *) (((B) - 1) * BLOCKSIZE + heap->heapbase))
+
+
+/* Data structure giving per-block information. */
+typedef union {
+
+ /* Heap information for a busy block. */
+ struct {
+
+ /* Zero for a large block, or positive giving the
+ logarithm to the base two of the fragment size. */
+ int type;
+
+ union {
+ struct {
+ size_t nfree; /* Free fragments in a fragmented block. */
+ size_t first; /* First free fragment of the block. */
+ } frag;
+
+ /* Size (in blocks) of a large cluster. */
+ size_t size;
+ } info;
+ } busy;
+
+ /* Heap information for a free block
+ (that may be the first of a free cluster). */
+ struct {
+ size_t size; /* Size (in blocks) of a free cluster. */
+ size_t next; /* Index of next free cluster. */
+ size_t prev; /* Index of previous free cluster. */
+ } free;
+} shmalloc_info;
+
+/* Doubly linked lists of free fragments. */
+struct list {
+ struct list *next;
+ struct list *prev;
+};
+
+
+#define SHMEMDESC_FUNC_NAME_LENGTH 48
+#define SHMEMDESC_FILE_NAME_LENGTH 24
+
+/* Used for debugging. */
+typedef struct {
+ DirectLink link;
+
+ const void *mem;
+ size_t bytes;
+ char func[SHMEMDESC_FUNC_NAME_LENGTH];
+ char file[SHMEMDESC_FILE_NAME_LENGTH];
+ unsigned int line;
+
+ FusionID fid;
+} SHMemDesc;
+
+
+struct __shmalloc_heap {
+ int magic;
+
+ /* Pointer to first block of the heap. */
+ char *heapbase;
+
+ /* Block information table indexed by block number giving per-block information. */
+ shmalloc_info *heapinfo;
+
+ /* Number of info entries. */
+ size_t heapsize;
+
+ /* Current search index for the heap table. */
+ size_t heapindex;
+
+ /* Limit of valid info table indices. */
+ size_t heaplimit;
+
+#if 1 /* Adapted from Mike */
+ /* Count of large blocks allocated for each fragment size. */
+ int fragblocks[BLOCKLOG];
+#endif
+
+ /* Free list headers for each fragment size. */
+ struct list fraghead[BLOCKLOG];
+
+ /* Instrumentation. */
+ size_t chunks_used;
+ size_t bytes_used;
+ size_t chunks_free;
+ size_t bytes_free;
+
+ /* Total size of heap in bytes. */
+ int size;
+
+ /* Back pointer to shared memory pool. */
+ FusionSHMPoolShared *pool;
+};
+
+
+void *_fusion_shmalloc (shmalloc_heap *heap, size_t __size);
+
+void *_fusion_shrealloc (shmalloc_heap *heap, void *__ptr, size_t __size);
+
+void _fusion_shfree (shmalloc_heap *heap, void *__ptr);
+
+
+DirectResult __shmalloc_init_heap( FusionSHM *shm,
+ const char *filename,
+ void *addr_base,
+ int space,
+ int *ret_fd,
+ int *ret_size );
+
+DirectResult __shmalloc_join_heap( FusionSHM *shm,
+ const char *filename,
+ void *addr_base,
+ int size,
+ int *ret_fd );
+
+void *__shmalloc_brk ( shmalloc_heap *heap,
+ int increment );
+
+
+#endif
+